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

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

Issue 661179: Inline Math.sqrt(). ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 | « src/ia32/codegen-ia32.h ('k') | src/math.js » ('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 5258 matching lines...) Expand 10 before | Expand all | Expand 10 after
5269 Load(args->at(0)); 5269 Load(args->at(0));
5270 Result value = frame_->Pop(); 5270 Result value = frame_->Pop();
5271 value.ToRegister(); 5271 value.ToRegister();
5272 ASSERT(value.is_valid()); 5272 ASSERT(value.is_valid());
5273 __ test(value.reg(), Immediate(kSmiTagMask | 0x80000000)); 5273 __ test(value.reg(), Immediate(kSmiTagMask | 0x80000000));
5274 value.Unuse(); 5274 value.Unuse();
5275 destination()->Split(zero); 5275 destination()->Split(zero);
5276 } 5276 }
5277 5277
5278 5278
5279 // Generates the Math.pow method - only handles special cases and branches to
5280 // the runtime system if not. Uses eax to store result and as temporary reg.
5281 void CodeGenerator::GeneratePow(ZoneList<Expression*>* args) {
5282 ASSERT(args->length() == 2);
5283 if (CpuFeatures::IsSupported(SSE2)) {
5284 CpuFeatures::Scope use_sse2(SSE2);
5285 Load(args->at(0));
5286 Load(args->at(1));
5287 Label go_runtime;
5288 Label return_preg;
5289 Result p = allocator()->Allocate(eax);
5290 Result y = frame_->Pop();
5291 Result x= frame_->Pop();
5292 if (p.is_valid() && p.reg().is(eax)) {
5293 x.ToRegister();
5294 y.ToRegister();
5295 frame_->Spill(x.reg());
5296 frame_->Spill(y.reg());
5297 ASSERT(x.is_valid());
5298 ASSERT(y.is_valid());
5299
5300 // Save 1 in xmm3 - we need this several times later on
5301 __ mov(p.reg(), Immediate(1));
5302 __ cvtsi2sd(xmm3, Operand(p.reg()));
5303
5304 Label y_nonsmi;
5305 Label x_is_double;
5306 // If y is a heap number go to that specific case.
5307 __ test(y.reg(), Immediate(kSmiTagMask));
5308 __ j(not_zero, &y_nonsmi);
5309 __ test(x.reg(), Immediate(kSmiTagMask));
5310 __ j(not_zero, &x_is_double);
5311
5312 // Bot numbers are smis.
5313 Label powi;
5314 __ SmiUntag(x.reg());
5315 __ cvtsi2sd(xmm0, Operand(x.reg()));
5316 __ jmp(&powi);
5317 // Y is smi and x is a double.
5318 __ bind(&x_is_double);
5319 __ cmp(FieldOperand(x.reg(), HeapObject::kMapOffset),
5320 Factory::heap_number_map());
5321 __ j(not_equal, &go_runtime);
5322 __ movdbl(xmm0, FieldOperand(x.reg(), HeapNumber::kValueOffset));
5323
5324 __ bind(&powi);
5325 __ SmiUntag(y.reg());
5326
5327 // Save y in x as we need to check if y is negative later.
5328 __ mov(x.reg(), y.reg());
5329
5330
5331 // Get absolute value of y.
5332 Label no_neg;
5333 __ cmp(y.reg(), 0);
5334 __ j(greater_equal, &no_neg);
5335 __ neg(y.reg());
5336 __ bind(&no_neg);
5337
5338 // Optimized version of pow if y is an integer.
5339 // Load xmm1 with 1.
5340 __ movsd(xmm1, xmm3);
5341 Label while_true;
5342 Label no_multiply;
5343 Label powi_done;
5344 Label allocate_and_return;
5345 __ bind(&while_true);
5346 __ shr(y.reg(), 1);
5347 __ j(not_carry, &no_multiply);
5348 __ mulsd(xmm1, xmm0);
5349 __ bind(&no_multiply);
5350 __ test(y.reg(), Operand(y.reg()));
5351 __ mulsd(xmm0, xmm0);
5352 __ j(not_zero, &while_true);
5353
5354 __ bind(&powi_done);
5355 // x has the original value of y - if y is negative return 1/result.
5356 __ test(x.reg(), Operand(x.reg()));
5357 __ j(positive, &allocate_and_return);
5358 // Special case if xmm1 has reached infinity
5359 __ mov(p.reg(), Immediate(0x7FB00000));
5360 __ movd(xmm0, Operand(p.reg()));
5361 __ cvtss2sd(xmm0, xmm0);
5362 __ ucomisd(xmm0, xmm1);
5363 __ j(equal, &go_runtime);
5364 __ divsd(xmm3, xmm1);
5365 __ movsd(xmm1, xmm3);
5366 __ jmp(&allocate_and_return);
5367
5368 // y (or both) is a double - no matter what we should now work
5369 // on doubles.
5370 __ bind(&y_nonsmi);
5371 __ cmp(FieldOperand(y.reg(), HeapObject::kMapOffset),
5372 Factory::heap_number_map());
5373 __ j(not_equal, &go_runtime);
5374 // Y must be a double.
5375 __ movdbl(xmm1, FieldOperand(y.reg(), HeapNumber::kValueOffset));
5376 // Test if y is nan.
5377 __ ucomisd(xmm1, xmm1);
5378 __ j(parity_even, &go_runtime);
5379
5380 Label x_not_smi;
5381 Label handle_special_cases;
5382 __ test(x.reg(), Immediate(kSmiTagMask));
5383 __ j(not_zero, &x_not_smi);
5384 __ SmiUntag(x.reg());
5385 __ cvtsi2sd(xmm0, Operand(x.reg()));
5386 __ jmp(&handle_special_cases);
5387 __ bind(&x_not_smi);
5388 __ cmp(FieldOperand(x.reg(), HeapObject::kMapOffset),
5389 Factory::heap_number_map());
5390 __ j(not_equal, &go_runtime);
5391 __ mov(p.reg(), FieldOperand(x.reg(), HeapNumber::kExponentOffset));
5392 __ and_(p.reg(), HeapNumber::kExponentMask);
5393 __ cmp(Operand(p.reg()), Immediate(HeapNumber::kExponentMask));
5394 // x is NaN or +/-Infinity
5395 __ j(greater_equal, &go_runtime);
5396 __ movdbl(xmm0, FieldOperand(x.reg(), HeapNumber::kValueOffset));
5397
5398 // x is in xmm0 and y is in xmm1.
5399 __ bind(&handle_special_cases);
5400 Label not_minus_half;
5401 // Test for -0.5.
5402 // Load xmm2 with -0.5.
5403 __ mov(p.reg(), Immediate(0xBF000000));
5404 __ movd(xmm2, Operand(p.reg()));
5405 __ cvtss2sd(xmm2, xmm2);
5406 // xmm2 now has -0.5.
5407 __ ucomisd(xmm2, xmm1);
5408 __ j(not_equal, &not_minus_half);
5409
5410 // Calculates reciprocal of square root.
5411 // Note that 1/sqrt(x) = sqrt(1/x))
5412 __ divsd(xmm3, xmm0);
5413 __ movsd(xmm1, xmm3);
5414 __ sqrtsd(xmm1, xmm1);
5415 __ jmp(&allocate_and_return);
5416
5417 // Test for 0.5.
5418 __ bind(&not_minus_half);
5419 // Load xmm2 with 0.5.
5420 // Since xmm3 is 1 and xmm2 is -0.5 this is simply xmm2 = xmm3
5421 __ addsd(xmm2, xmm3);
5422 // xmm2 now has 0.5.
5423 __ ucomisd(xmm2, xmm1);
5424 __ j(not_equal, &go_runtime);
5425 // Calculates square root.
5426 __ movsd(xmm1, xmm0);
5427 __ sqrtsd(xmm1, xmm1);
5428
5429 __ bind(&allocate_and_return);
5430 __ AllocateHeapNumber(p.reg(), y.reg(), x.reg(), &go_runtime);
5431 __ movdbl(FieldOperand(p.reg(), HeapNumber::kValueOffset), xmm1);
5432 __ jmp(&return_preg);
5433 }
5434 __ bind(&go_runtime);
5435 x.Unuse();
5436 y.Unuse();
5437 p.Unuse();
5438 Load(args->at(0));
5439 Load(args->at(1));
5440 frame_->CallRuntime(Runtime::kMath_pow_cfunction, 2);
5441
5442 // Since we store the result in p.reg() which is eax - return this value.
5443 // If we called runtime the result is also in eax.
5444 __ bind(&return_preg);
5445 frame_->Push(eax);
5446 } else { // Simply call runtime.
5447 Load(args->at(0));
5448 Load(args->at(1));
5449 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2);
5450 frame_->Push(&res);
5451 }
5452 }
5453
5454
5455 // This generates code that performs a charCodeAt() call or returns 5279 // This generates code that performs a charCodeAt() call or returns
5456 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt. 5280 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
5457 // It can handle flat, 8 and 16 bit characters and cons strings where the 5281 // It can handle flat, 8 and 16 bit characters and cons strings where the
5458 // answer is found in the left hand branch of the cons. The slow case will 5282 // answer is found in the left hand branch of the cons. The slow case will
5459 // flatten the string, which will ensure that the answer is in the left hand 5283 // flatten the string, which will ensure that the answer is in the left hand
5460 // side the next time around. 5284 // side the next time around.
5461 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { 5285 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
5462 Comment(masm_, "[ GenerateFastCharCodeAt"); 5286 Comment(masm_, "[ GenerateFastCharCodeAt");
5463 ASSERT(args->length() == 2); 5287 ASSERT(args->length() == 2);
5464 5288
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
6033 ASSERT_EQ(args->length(), 1); 5857 ASSERT_EQ(args->length(), 1);
6034 5858
6035 // Load the argument on the stack and call the stub. 5859 // Load the argument on the stack and call the stub.
6036 Load(args->at(0)); 5860 Load(args->at(0));
6037 NumberToStringStub stub; 5861 NumberToStringStub stub;
6038 Result result = frame_->CallStub(&stub, 1); 5862 Result result = frame_->CallStub(&stub, 1);
6039 frame_->Push(&result); 5863 frame_->Push(&result);
6040 } 5864 }
6041 5865
6042 5866
5867 // Generates the Math.pow method - only handles special cases and branches to
5868 // the runtime system if not.Please note - this function assumes that
5869 // the callsite has executed ToNumber on both arguments and that the
5870 // arguments are not the same identifier.
5871 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
5872 ASSERT(args->length() == 2);
5873 Load(args->at(0));
5874 Load(args->at(1));
5875 if (!CpuFeatures::IsSupported(SSE2)) {
5876 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2);
5877 frame_->Push(&res);
5878 } else {
5879 CpuFeatures::Scope use_sse2(SSE2);
5880 Label allocate_return;
5881 // Load the two operands while leaving the values on the frame.
5882 frame()->Dup();
5883 Result exponent = frame()->Pop();
5884 exponent.ToRegister();
5885 frame()->Spill(exponent.reg());
5886 frame()->PushElementAt(1);
5887 Result base = frame()->Pop();
5888 base.ToRegister();
5889 frame()->Spill(base.reg());
5890
5891 Result answer = allocator()->Allocate();
5892 ASSERT(answer.is_valid());
5893 // We can safely assume that the base and exponent is not in the same
5894 // register since we only call this from one callsite (math.js).
5895 ASSERT(!exponent.reg().is(base.reg()));
5896 JumpTarget call_runtime;
5897
5898 // Save 1 in xmm3 - we need this several times later on.
5899 __ mov(answer.reg(), Immediate(1));
5900 __ cvtsi2sd(xmm3, Operand(answer.reg()));
5901
5902 Label exponent_nonsmi;
5903 Label base_nonsmi;
5904 // If the exponent is a heap number go to that specific case.
5905 __ test(exponent.reg(), Immediate(kSmiTagMask));
5906 __ j(not_zero, &exponent_nonsmi);
5907 __ test(base.reg(), Immediate(kSmiTagMask));
5908 __ j(not_zero, &base_nonsmi);
5909
5910 // Optimized version when y is an integer.
5911 Label powi;
5912 __ SmiUntag(base.reg());
5913 __ cvtsi2sd(xmm0, Operand(base.reg()));
5914 __ jmp(&powi);
5915 // exponent is smi and base is a heapnumber.
5916 __ bind(&base_nonsmi);
5917 __ cmp(FieldOperand(base.reg(), HeapObject::kMapOffset),
5918 Factory::heap_number_map());
Lasse Reichstein 2010/03/08 13:17:01 Indentation? Ditto for other two.
5919 call_runtime.Branch(not_zero);
Lasse Reichstein 2010/03/08 13:17:01 not_zero->not_equal (I know they are identical, bu
5920
5921 __ movdbl(xmm0, FieldOperand(base.reg(), HeapNumber::kValueOffset));
5922
5923 // Optimized version of pow if y is an integer.
5924 __ bind(&powi);
5925 __ SmiUntag(exponent.reg());
5926
5927 // Save exponent in base as we need to check if exponent is negative later.
5928 // We know that base and exponent are in different registers.
5929 __ mov(base.reg(), exponent.reg());
5930
5931 // Get absolute value of exponent.
5932 Label no_neg;
5933 __ cmp(exponent.reg(), 0);
5934 __ j(greater_equal, &no_neg);
5935 __ neg(exponent.reg());
5936 __ bind(&no_neg);
5937
5938 // Load xmm1 with 1.
5939 __ movsd(xmm1, xmm3);
5940 Label while_true;
5941 Label no_multiply;
5942
5943 // Label allocate_and_return;
5944 __ bind(&while_true);
5945 __ shr(exponent.reg(), 1);
5946 __ j(not_carry, &no_multiply);
5947 __ mulsd(xmm1, xmm0);
5948 __ bind(&no_multiply);
5949 __ test(exponent.reg(), Operand(exponent.reg()));
5950 __ mulsd(xmm0, xmm0);
5951 __ j(not_zero, &while_true);
5952
5953 // x has the original value of y - if y is negative return 1/result.
5954 __ test(base.reg(), Operand(base.reg()));
5955 __ j(positive, &allocate_return);
5956 // Special case if xmm1 has reached infinity.
5957 __ mov(answer.reg(), Immediate(0x7FB00000));
5958 __ movd(xmm0, Operand(answer.reg()));
5959 __ cvtss2sd(xmm0, xmm0);
5960 __ ucomisd(xmm0, xmm1);
5961 call_runtime.Branch(equal);
5962 __ divsd(xmm3, xmm1);
5963 __ movsd(xmm1, xmm3);
5964 __ jmp(&allocate_return);
5965
5966 // exponent (or both) is a heapnumber - no matter what we should now work
5967 // on doubles.
5968 __ bind(&exponent_nonsmi);
5969 __ cmp(FieldOperand(exponent.reg(), HeapObject::kMapOffset),
5970 Factory::heap_number_map());
5971 call_runtime.Branch(not_zero);
5972 __ movdbl(xmm1, FieldOperand(exponent.reg(), HeapNumber::kValueOffset));
5973 // Test if exponent is nan.
5974 __ ucomisd(xmm1, xmm1);
5975 call_runtime.Branch(parity_even);
5976
5977 Label base_not_smi;
5978 Label handle_special_cases;
5979 __ test(base.reg(), Immediate(kSmiTagMask));
5980 __ j(not_zero, &base_not_smi);
5981 __ SmiUntag(base.reg());
5982 __ cvtsi2sd(xmm0, Operand(base.reg()));
5983 __ jmp(&handle_special_cases);
5984 __ bind(&base_not_smi);
5985 __ cmp(FieldOperand(base.reg(), HeapObject::kMapOffset),
5986 Factory::heap_number_map());
5987 call_runtime.Branch(not_zero);
5988 __ mov(answer.reg(), FieldOperand(base.reg(), HeapNumber::kExponentOffset));
5989 __ and_(answer.reg(), HeapNumber::kExponentMask);
5990 __ cmp(Operand(answer.reg()), Immediate(HeapNumber::kExponentMask));
5991 // base is NaN or +/-Infinity
5992 call_runtime.Branch(greater_equal);
5993 __ movdbl(xmm0, FieldOperand(base.reg(), HeapNumber::kValueOffset));
5994
5995 // base is in xmm0 and exponent is in xmm1.
5996 __ bind(&handle_special_cases);
5997 Label not_minus_half;
5998 // Test for -0.5.
5999 // Load xmm2 with -0.5.
6000 __ mov(answer.reg(), Immediate(0xBF000000));
6001 __ movd(xmm2, Operand(answer.reg()));
6002 __ cvtss2sd(xmm2, xmm2);
6003 // xmm2 now has -0.5.
6004 __ ucomisd(xmm2, xmm1);
6005 __ j(not_equal, &not_minus_half);
6006
6007 // Calculates reciprocal of square root.
6008 // Note that 1/sqrt(x) = sqrt(1/x))
6009 __ divsd(xmm3, xmm0);
6010 __ movsd(xmm1, xmm3);
6011 __ sqrtsd(xmm1, xmm1);
6012 __ jmp(&allocate_return);
6013
6014 // Test for 0.5.
6015 __ bind(&not_minus_half);
6016 // Load xmm2 with 0.5.
6017 // Since xmm3 is 1 and xmm2 is -0.5 this is simply xmm2 + xmm3.
6018 __ addsd(xmm2, xmm3);
6019 // xmm2 now has 0.5.
6020 __ comisd(xmm2, xmm1);
6021 call_runtime.Branch(not_equal);
6022 // Calculates square root.
6023 __ movsd(xmm1, xmm0);
6024 __ sqrtsd(xmm1, xmm1);
6025
6026 JumpTarget done;
6027 Label failure, success;
6028 __ bind(&allocate_return);
6029 // Make a copy of the frame to enable us to handle allocation
6030 // failure after the JumpTarget jump.
6031 VirtualFrame* clone = new VirtualFrame(frame());
6032 __ AllocateHeapNumber(answer.reg(), exponent.reg(),
6033 base.reg(), &failure);
6034 __ movdbl(FieldOperand(answer.reg(), HeapNumber::kValueOffset), xmm1);
6035 // Remove the two original values from the frame - we only need those
6036 // in the case where we branch to runtime.
6037 frame()->Drop(2);
6038 exponent.Unuse();
6039 base.Unuse();
6040 done.Jump(&answer);
6041 // Use the copy of the original frame as our current frame.
6042 RegisterFile empty_regs;
6043 SetFrame(clone, &empty_regs);
6044 // If we experience an allocation failure we branch to runtime.
6045 __ bind(&failure);
6046 call_runtime.Bind();
6047 answer = frame()->CallRuntime(Runtime::kMath_pow_cfunction, 2);
6048
6049 done.Bind(&answer);
6050 frame()->Push(&answer);
6051 }
6052 }
6053
6054
6043 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { 6055 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
6044 ASSERT_EQ(args->length(), 1); 6056 ASSERT_EQ(args->length(), 1);
6045 Load(args->at(0)); 6057 Load(args->at(0));
6046 TranscendentalCacheStub stub(TranscendentalCache::SIN); 6058 TranscendentalCacheStub stub(TranscendentalCache::SIN);
6047 Result result = frame_->CallStub(&stub, 1); 6059 Result result = frame_->CallStub(&stub, 1);
6048 frame_->Push(&result); 6060 frame_->Push(&result);
6049 } 6061 }
6050 6062
6051 6063
6052 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { 6064 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
6053 ASSERT_EQ(args->length(), 1); 6065 ASSERT_EQ(args->length(), 1);
6054 Load(args->at(0)); 6066 Load(args->at(0));
6055 TranscendentalCacheStub stub(TranscendentalCache::COS); 6067 TranscendentalCacheStub stub(TranscendentalCache::COS);
6056 Result result = frame_->CallStub(&stub, 1); 6068 Result result = frame_->CallStub(&stub, 1);
6057 frame_->Push(&result); 6069 frame_->Push(&result);
6058 } 6070 }
6059 6071
6060 6072
6073 // Generates the Math.sqrt method. Please note - this function assumes that
6074 // the callsite has executed ToNumber on the argument.
6075 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
6076 ASSERT_EQ(args->length(), 1);
6077 Load(args->at(0));
6078
6079 if (!CpuFeatures::IsSupported(SSE2)) {
6080 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1);
6081 frame()->Push(&result);
6082 } else {
6083 CpuFeatures::Scope use_sse2(SSE2);
6084 // Leave original value on the frame if we need to call runtime.
6085 frame()->Dup();
6086 Result result = frame()->Pop();
6087 result.ToRegister();
6088 frame()->Spill(result.reg());
6089 Label runtime;
6090 Label non_smi;
6091 Label load_done;
6092 JumpTarget end;
6093
6094 __ test(result.reg(), Immediate(kSmiTagMask));
6095 __ j(not_zero, &non_smi);
6096 __ SmiUntag(result.reg());
6097 __ cvtsi2sd(xmm0, Operand(result.reg()));
6098 __ jmp(&load_done);
6099 __ bind(&non_smi);
6100 __ cmp(FieldOperand(result.reg(), HeapObject::kMapOffset),
6101 Factory::heap_number_map());
6102 __ j(not_zero, &runtime);
6103 __ movdbl(xmm0, FieldOperand(result.reg(), HeapNumber::kValueOffset));
6104
6105 __ bind(&load_done);
6106 __ sqrtsd(xmm0, xmm0);
6107 // A copy of the virtual frame to allow us to go to runtime after the
6108 // JumpTarget jump.
6109 Result scratch = allocator()->Allocate();
6110 VirtualFrame* clone = new VirtualFrame(frame());
6111 __ AllocateHeapNumber(result.reg(), scratch.reg(), no_reg, &runtime);
6112
6113 __ movdbl(FieldOperand(result.reg(), HeapNumber::kValueOffset), xmm0);
6114 frame()->Drop(1);
6115 scratch.Unuse();
6116 end.Jump(&result);
6117 // We only branch to runtime if we have an allocation error.
6118 // Use the copy of the original frame as our current frame.
6119 RegisterFile empty_regs;
6120 SetFrame(clone, &empty_regs);
6121 __ bind(&runtime);
6122 result = frame()->CallRuntime(Runtime::kMath_sqrt, 1);
6123
6124 end.Bind(&result);
6125 frame()->Push(&result);
6126 }
6127 }
6128
6129
6061 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 6130 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
6062 if (CheckForInlineRuntimeCall(node)) { 6131 if (CheckForInlineRuntimeCall(node)) {
6063 return; 6132 return;
6064 } 6133 }
6065 6134
6066 ZoneList<Expression*>* args = node->arguments(); 6135 ZoneList<Expression*>* args = node->arguments();
6067 Comment cmnt(masm_, "[ CallRuntime"); 6136 Comment cmnt(masm_, "[ CallRuntime");
6068 Runtime::Function* function = node->function(); 6137 Runtime::Function* function = node->function();
6069 6138
6070 if (function == NULL) { 6139 if (function == NULL) {
(...skipping 5313 matching lines...) Expand 10 before | Expand all | Expand 10 after
11384 11453
11385 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 11454 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
11386 // tagged as a small integer. 11455 // tagged as a small integer.
11387 __ bind(&runtime); 11456 __ bind(&runtime);
11388 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 11457 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
11389 } 11458 }
11390 11459
11391 #undef __ 11460 #undef __
11392 11461
11393 } } // namespace v8::internal 11462 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/math.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698