OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 __ j(not_equal, &true_result); | 266 __ j(not_equal, &true_result); |
267 // HeapNumber => false iff +0, -0, or NaN. | 267 // HeapNumber => false iff +0, -0, or NaN. |
268 // These three cases set the zero flag when compared to zero using ucomisd. | 268 // These three cases set the zero flag when compared to zero using ucomisd. |
269 __ xorpd(xmm0, xmm0); | 269 __ xorpd(xmm0, xmm0); |
270 __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); | 270 __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); |
271 __ j(zero, &false_result); | 271 __ j(zero, &false_result); |
272 // Fall through to |true_result|. | 272 // Fall through to |true_result|. |
273 | 273 |
274 // Return 1/0 for true/false in rax. | 274 // Return 1/0 for true/false in rax. |
275 __ bind(&true_result); | 275 __ bind(&true_result); |
276 __ movq(rax, Immediate(1)); | 276 __ Set(rax, 1); |
277 __ ret(1 * kPointerSize); | 277 __ ret(1 * kPointerSize); |
278 __ bind(&false_result); | 278 __ bind(&false_result); |
279 __ Set(rax, 0); | 279 __ Set(rax, 0); |
280 __ ret(1 * kPointerSize); | 280 __ ret(1 * kPointerSize); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 class FloatingPointHelper : public AllStatic { | 284 class FloatingPointHelper : public AllStatic { |
285 public: | 285 public: |
286 // Load the operands from rdx and rax into xmm0 and xmm1, as doubles. | 286 // Load the operands from rdx and rax into xmm0 and xmm1, as doubles. |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 Label load_arg2, done; | 1274 Label load_arg2, done; |
1275 | 1275 |
1276 __ JumpIfNotSmi(rdx, &arg1_is_object); | 1276 __ JumpIfNotSmi(rdx, &arg1_is_object); |
1277 __ SmiToInteger32(r8, rdx); | 1277 __ SmiToInteger32(r8, rdx); |
1278 __ jmp(&load_arg2); | 1278 __ jmp(&load_arg2); |
1279 | 1279 |
1280 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). | 1280 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). |
1281 __ bind(&check_undefined_arg1); | 1281 __ bind(&check_undefined_arg1); |
1282 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); | 1282 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); |
1283 __ j(not_equal, conversion_failure); | 1283 __ j(not_equal, conversion_failure); |
1284 __ movl(r8, Immediate(0)); | 1284 __ Set(r8, 0); |
1285 __ jmp(&load_arg2); | 1285 __ jmp(&load_arg2); |
1286 | 1286 |
1287 __ bind(&arg1_is_object); | 1287 __ bind(&arg1_is_object); |
1288 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map); | 1288 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map); |
1289 __ j(not_equal, &check_undefined_arg1); | 1289 __ j(not_equal, &check_undefined_arg1); |
1290 // Get the untagged integer version of the rdx heap number in rcx. | 1290 // Get the untagged integer version of the rdx heap number in rcx. |
1291 IntegerConvert(masm, r8, rdx); | 1291 IntegerConvert(masm, r8, rdx); |
1292 | 1292 |
1293 // Here r8 has the untagged integer, rax has a Smi or a heap number. | 1293 // Here r8 has the untagged integer, rax has a Smi or a heap number. |
1294 __ bind(&load_arg2); | 1294 __ bind(&load_arg2); |
1295 // Test if arg2 is a Smi. | 1295 // Test if arg2 is a Smi. |
1296 __ JumpIfNotSmi(rax, &arg2_is_object); | 1296 __ JumpIfNotSmi(rax, &arg2_is_object); |
1297 __ SmiToInteger32(rcx, rax); | 1297 __ SmiToInteger32(rcx, rax); |
1298 __ jmp(&done); | 1298 __ jmp(&done); |
1299 | 1299 |
1300 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). | 1300 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). |
1301 __ bind(&check_undefined_arg2); | 1301 __ bind(&check_undefined_arg2); |
1302 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 1302 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
1303 __ j(not_equal, conversion_failure); | 1303 __ j(not_equal, conversion_failure); |
1304 __ movl(rcx, Immediate(0)); | 1304 __ Set(rcx, 0); |
1305 __ jmp(&done); | 1305 __ jmp(&done); |
1306 | 1306 |
1307 __ bind(&arg2_is_object); | 1307 __ bind(&arg2_is_object); |
1308 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map); | 1308 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map); |
1309 __ j(not_equal, &check_undefined_arg2); | 1309 __ j(not_equal, &check_undefined_arg2); |
1310 // Get the untagged integer version of the rax heap number in rcx. | 1310 // Get the untagged integer version of the rax heap number in rcx. |
1311 IntegerConvert(masm, rcx, rax); | 1311 IntegerConvert(masm, rcx, rax); |
1312 __ bind(&done); | 1312 __ bind(&done); |
1313 __ movl(rax, r8); | 1313 __ movl(rax, r8); |
1314 } | 1314 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 __ bind(&try_float); | 1451 __ bind(&try_float); |
1452 } else if (FLAG_debug_code) { | 1452 } else if (FLAG_debug_code) { |
1453 __ AbortIfSmi(rax); | 1453 __ AbortIfSmi(rax); |
1454 } | 1454 } |
1455 | 1455 |
1456 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 1456 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |
1457 Heap::kHeapNumberMapRootIndex); | 1457 Heap::kHeapNumberMapRootIndex); |
1458 __ j(not_equal, &slow); | 1458 __ j(not_equal, &slow); |
1459 // Operand is a float, negate its value by flipping sign bit. | 1459 // Operand is a float, negate its value by flipping sign bit. |
1460 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); | 1460 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); |
1461 __ movq(kScratchRegister, Immediate(0x01)); | 1461 __ Set(kScratchRegister, 0x01); |
1462 __ shl(kScratchRegister, Immediate(63)); | 1462 __ shl(kScratchRegister, Immediate(63)); |
1463 __ xor_(rdx, kScratchRegister); // Flip sign. | 1463 __ xor_(rdx, kScratchRegister); // Flip sign. |
1464 // rdx is value to store. | 1464 // rdx is value to store. |
1465 if (overwrite_ == UNARY_OVERWRITE) { | 1465 if (overwrite_ == UNARY_OVERWRITE) { |
1466 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); | 1466 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); |
1467 } else { | 1467 } else { |
1468 __ AllocateHeapNumber(rcx, rbx, &slow); | 1468 __ AllocateHeapNumber(rcx, rbx, &slow); |
1469 // rcx: allocated 'empty' number | 1469 // rcx: allocated 'empty' number |
1470 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); | 1470 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); |
1471 __ movq(rax, rcx); | 1471 __ movq(rax, rcx); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 // rax = exponent | 1523 // rax = exponent |
1524 // rcx = temporary, result | 1524 // rcx = temporary, result |
1525 | 1525 |
1526 Label allocate_return, call_runtime; | 1526 Label allocate_return, call_runtime; |
1527 | 1527 |
1528 // Load input parameters. | 1528 // Load input parameters. |
1529 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 1529 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1530 __ movq(rax, Operand(rsp, 1 * kPointerSize)); | 1530 __ movq(rax, Operand(rsp, 1 * kPointerSize)); |
1531 | 1531 |
1532 // Save 1 in xmm3 - we need this several times later on. | 1532 // Save 1 in xmm3 - we need this several times later on. |
1533 __ movl(rcx, Immediate(1)); | 1533 __ Set(rcx, 1); |
1534 __ cvtlsi2sd(xmm3, rcx); | 1534 __ cvtlsi2sd(xmm3, rcx); |
1535 | 1535 |
1536 Label exponent_nonsmi; | 1536 Label exponent_nonsmi; |
1537 Label base_nonsmi; | 1537 Label base_nonsmi; |
1538 // If the exponent is a heap number go to that specific case. | 1538 // If the exponent is a heap number go to that specific case. |
1539 __ JumpIfNotSmi(rax, &exponent_nonsmi); | 1539 __ JumpIfNotSmi(rax, &exponent_nonsmi); |
1540 __ JumpIfNotSmi(rdx, &base_nonsmi); | 1540 __ JumpIfNotSmi(rdx, &base_nonsmi); |
1541 | 1541 |
1542 // Optimized version when both exponent and base are smis. | 1542 // Optimized version when both exponent and base are smis. |
1543 Label powi; | 1543 Label powi; |
(...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3246 == 0xB0 - 0x100); | 3246 == 0xB0 - 0x100); |
3247 __ movl(rax, Immediate(0xB0)); // TrueValue is at -10 * kPointerSize. | 3247 __ movl(rax, Immediate(0xB0)); // TrueValue is at -10 * kPointerSize. |
3248 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); | 3248 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); |
3249 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); | 3249 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); |
3250 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); | 3250 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); |
3251 if (FLAG_debug_code) { | 3251 if (FLAG_debug_code) { |
3252 __ movl(rax, Immediate(kWordBeforeResultValue)); | 3252 __ movl(rax, Immediate(kWordBeforeResultValue)); |
3253 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); | 3253 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); |
3254 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)."); | 3254 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)."); |
3255 } | 3255 } |
3256 __ xorl(rax, rax); | 3256 __ Set(rax, 0); |
3257 } | 3257 } |
3258 __ ret(2 * kPointerSize + extra_stack_space); | 3258 __ ret(2 * kPointerSize + extra_stack_space); |
3259 | 3259 |
3260 __ bind(&is_not_instance); | 3260 __ bind(&is_not_instance); |
3261 if (!HasCallSiteInlineCheck()) { | 3261 if (!HasCallSiteInlineCheck()) { |
3262 // We have to store a non-zero value in the cache. | 3262 // We have to store a non-zero value in the cache. |
3263 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); | 3263 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); |
3264 } else { | 3264 } else { |
3265 // Store offset of false in the root array at the inline check site. | 3265 // Store offset of false in the root array at the inline check site. |
3266 ASSERT((Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias | 3266 ASSERT((Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias |
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4105 __ sarl(scratch, Immediate(11)); | 4105 __ sarl(scratch, Immediate(11)); |
4106 __ xorl(hash, scratch); | 4106 __ xorl(hash, scratch); |
4107 // hash += hash << 15; | 4107 // hash += hash << 15; |
4108 __ movl(scratch, hash); | 4108 __ movl(scratch, hash); |
4109 __ shll(scratch, Immediate(15)); | 4109 __ shll(scratch, Immediate(15)); |
4110 __ addl(hash, scratch); | 4110 __ addl(hash, scratch); |
4111 | 4111 |
4112 // if (hash == 0) hash = 27; | 4112 // if (hash == 0) hash = 27; |
4113 Label hash_not_zero; | 4113 Label hash_not_zero; |
4114 __ j(not_zero, &hash_not_zero); | 4114 __ j(not_zero, &hash_not_zero); |
4115 __ movl(hash, Immediate(27)); | 4115 __ Set(hash, 27); |
4116 __ bind(&hash_not_zero); | 4116 __ bind(&hash_not_zero); |
4117 } | 4117 } |
4118 | 4118 |
4119 void SubStringStub::Generate(MacroAssembler* masm) { | 4119 void SubStringStub::Generate(MacroAssembler* masm) { |
4120 Label runtime; | 4120 Label runtime; |
4121 | 4121 |
4122 // Stack frame on entry. | 4122 // Stack frame on entry. |
4123 // rsp[0]: return address | 4123 // rsp[0]: return address |
4124 // rsp[8]: to | 4124 // rsp[8]: to |
4125 // rsp[16]: from | 4125 // rsp[16]: from |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4301 __ SmiToInteger32(min_length, min_length); | 4301 __ SmiToInteger32(min_length, min_length); |
4302 | 4302 |
4303 // Registers scratch2 and scratch3 are free. | 4303 // Registers scratch2 and scratch3 are free. |
4304 NearLabel result_not_equal; | 4304 NearLabel result_not_equal; |
4305 Label loop; | 4305 Label loop; |
4306 { | 4306 { |
4307 // Check characters 0 .. min_length - 1 in a loop. | 4307 // Check characters 0 .. min_length - 1 in a loop. |
4308 // Use scratch3 as loop index, min_length as limit and scratch2 | 4308 // Use scratch3 as loop index, min_length as limit and scratch2 |
4309 // for computation. | 4309 // for computation. |
4310 const Register index = scratch3; | 4310 const Register index = scratch3; |
4311 __ movl(index, Immediate(0)); // Index into strings. | 4311 __ Set(index, 0); // Index into strings. |
4312 __ bind(&loop); | 4312 __ bind(&loop); |
4313 // Compare characters. | 4313 // Compare characters. |
4314 // TODO(lrn): Could we load more than one character at a time? | 4314 // TODO(lrn): Could we load more than one character at a time? |
4315 __ movb(scratch2, FieldOperand(left, | 4315 __ movb(scratch2, FieldOperand(left, |
4316 index, | 4316 index, |
4317 times_1, | 4317 times_1, |
4318 SeqAsciiString::kHeaderSize)); | 4318 SeqAsciiString::kHeaderSize)); |
4319 // Increment index and use -1 modifier on next load to give | 4319 // Increment index and use -1 modifier on next load to give |
4320 // the previous load extra time to complete. | 4320 // the previous load extra time to complete. |
4321 __ addl(index, Immediate(1)); | 4321 __ addl(index, Immediate(1)); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4509 // Do a tail call to the rewritten stub. | 4509 // Do a tail call to the rewritten stub. |
4510 __ jmp(rdi); | 4510 __ jmp(rdi); |
4511 } | 4511 } |
4512 | 4512 |
4513 | 4513 |
4514 #undef __ | 4514 #undef __ |
4515 | 4515 |
4516 } } // namespace v8::internal | 4516 } } // namespace v8::internal |
4517 | 4517 |
4518 #endif // V8_TARGET_ARCH_X64 | 4518 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |