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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 23938003: Move ToInt conversions to the MacroAssembler for x64 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address review Created 7 years, 3 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/macro-assembler-ia32.cc ('k') | src/x64/lithium-codegen-x64.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 // xmm1 : untagged double input argument 1129 // xmm1 : untagged double input argument
1130 // Output: 1130 // Output:
1131 // xmm1 : untagged double result. 1131 // xmm1 : untagged double result.
1132 1132
1133 Label runtime_call; 1133 Label runtime_call;
1134 Label runtime_call_clear_stack; 1134 Label runtime_call_clear_stack;
1135 Label skip_cache; 1135 Label skip_cache;
1136 const bool tagged = (argument_type_ == TAGGED); 1136 const bool tagged = (argument_type_ == TAGGED);
1137 if (tagged) { 1137 if (tagged) {
1138 Label input_not_smi, loaded; 1138 Label input_not_smi, loaded;
1139
1139 // Test that rax is a number. 1140 // Test that rax is a number.
1140 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); 1141 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
1141 __ movq(rax, args.GetArgumentOperand(0)); 1142 __ movq(rax, args.GetArgumentOperand(0));
1142 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear); 1143 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
1143 // Input is a smi. Untag and load it onto the FPU stack. 1144 // Input is a smi. Untag and load it onto the FPU stack.
1144 // Then load the bits of the double into rbx. 1145 // Then load the bits of the double into rbx.
1145 __ SmiToInteger32(rax, rax); 1146 __ SmiToInteger32(rax, rax);
1146 __ subq(rsp, Immediate(kDoubleSize)); 1147 __ subq(rsp, Immediate(kDoubleSize));
1147 __ cvtlsi2sd(xmm1, rax); 1148 __ cvtlsi2sd(xmm1, rax);
1148 __ movsd(Operand(rsp, 0), xmm1); 1149 __ movsd(Operand(rsp, 0), xmm1);
1149 __ movq(rbx, xmm1); 1150 __ movq(rbx, xmm1);
1150 __ movq(rdx, xmm1); 1151 __ movq(rdx, xmm1);
1151 __ fld_d(Operand(rsp, 0)); 1152 __ fld_d(Operand(rsp, 0));
1152 __ addq(rsp, Immediate(kDoubleSize)); 1153 __ addq(rsp, Immediate(kDoubleSize));
1153 __ jmp(&loaded, Label::kNear); 1154 __ jmp(&loaded, Label::kNear);
1154 1155
1155 __ bind(&input_not_smi); 1156 __ bind(&input_not_smi);
1156 // Check if input is a HeapNumber. 1157 __ TaggedToI(rbx, rax, xmm1, TREAT_MINUS_ZERO_AS_ZERO, &runtime_call);
1157 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex);
1158 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
1159 __ j(not_equal, &runtime_call);
1160 // Input is a HeapNumber. Push it on the FPU stack and load its
1161 // bits into rbx.
1162 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
1163 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
1164 __ movq(rdx, rbx); 1158 __ movq(rdx, rbx);
1165 1159
1166 __ bind(&loaded); 1160 __ bind(&loaded);
1167 } else { // UNTAGGED. 1161 } else { // UNTAGGED.
1168 __ movq(rbx, xmm1); 1162 __ movq(rbx, xmm1);
1169 __ movq(rdx, xmm1); 1163 __ movq(rdx, xmm1);
1170 } 1164 }
1171 1165
1172 // ST[0] == double value, if TAGGED. 1166 // ST[0] == double value, if TAGGED.
1173 // rbx = bits of double value. 1167 // rbx = bits of double value.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 1433 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
1440 __ bind(&check_undefined_arg1); 1434 __ bind(&check_undefined_arg1);
1441 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); 1435 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
1442 __ j(not_equal, conversion_failure); 1436 __ j(not_equal, conversion_failure);
1443 __ Set(r8, 0); 1437 __ Set(r8, 0);
1444 __ jmp(&load_arg2); 1438 __ jmp(&load_arg2);
1445 1439
1446 __ bind(&arg1_is_object); 1440 __ bind(&arg1_is_object);
1447 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map); 1441 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map);
1448 __ j(not_equal, &check_undefined_arg1); 1442 __ j(not_equal, &check_undefined_arg1);
1449 // Get the untagged integer version of the rdx heap number in rcx. 1443 // Get the untagged integer version of the rdx heap number in r8.
1450 DoubleToIStub stub1(rdx, r8, HeapNumber::kValueOffset - kHeapObjectTag, 1444 __ TruncateHeapNumberToI(r8, rdx);
1451 true);
1452 __ call(stub1.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
1453 1445
1454 // Here r8 has the untagged integer, rax has a Smi or a heap number. 1446 // Here r8 has the untagged integer, rax has a Smi or a heap number.
1455 __ bind(&load_arg2); 1447 __ bind(&load_arg2);
1456 // Test if arg2 is a Smi. 1448 // Test if arg2 is a Smi.
1457 __ JumpIfNotSmi(rax, &arg2_is_object); 1449 __ JumpIfNotSmi(rax, &arg2_is_object);
1458 __ SmiToInteger32(rcx, rax); 1450 __ SmiToInteger32(rcx, rax);
1459 __ jmp(&done); 1451 __ jmp(&done);
1460 1452
1461 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). 1453 // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
1462 __ bind(&check_undefined_arg2); 1454 __ bind(&check_undefined_arg2);
1463 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 1455 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
1464 __ j(not_equal, conversion_failure); 1456 __ j(not_equal, conversion_failure);
1465 __ Set(rcx, 0); 1457 __ Set(rcx, 0);
1466 __ jmp(&done); 1458 __ jmp(&done);
1467 1459
1468 __ bind(&arg2_is_object); 1460 __ bind(&arg2_is_object);
1469 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map); 1461 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map);
1470 __ j(not_equal, &check_undefined_arg2); 1462 __ j(not_equal, &check_undefined_arg2);
1471 // Get the untagged integer version of the rax heap number in rcx. 1463 // Get the untagged integer version of the rax heap number in rcx.
1472 DoubleToIStub stub2(rax, rcx, HeapNumber::kValueOffset - kHeapObjectTag, 1464 __ TruncateHeapNumberToI(rcx, rax);
1473 true);
1474 __ call(stub2.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
1475 1465
1476 __ bind(&done); 1466 __ bind(&done);
1477 __ movl(rax, r8); 1467 __ movl(rax, r8);
1478 } 1468 }
1479 1469
1480 1470
1481 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) { 1471 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) {
1482 __ SmiToInteger32(kScratchRegister, rdx); 1472 __ SmiToInteger32(kScratchRegister, rdx);
1483 __ cvtlsi2sd(xmm0, kScratchRegister); 1473 __ cvtlsi2sd(xmm0, kScratchRegister);
1484 __ SmiToInteger32(kScratchRegister, rax); 1474 __ SmiToInteger32(kScratchRegister, rax);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 } else if (exponent_type_ == TAGGED) { 1631 } else if (exponent_type_ == TAGGED) {
1642 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 1632 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
1643 __ SmiToInteger32(exponent, exponent); 1633 __ SmiToInteger32(exponent, exponent);
1644 __ jmp(&int_exponent); 1634 __ jmp(&int_exponent);
1645 1635
1646 __ bind(&exponent_not_smi); 1636 __ bind(&exponent_not_smi);
1647 __ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset)); 1637 __ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
1648 } 1638 }
1649 1639
1650 if (exponent_type_ != INTEGER) { 1640 if (exponent_type_ != INTEGER) {
1651 Label fast_power; 1641 Label fast_power, try_arithmetic_simplification;
1652 // Detect integer exponents stored as double. 1642 // Detect integer exponents stored as double.
1643 __ DoubleToI(exponent, double_exponent, double_scratch,
1644 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification);
1645 __ jmp(&int_exponent);
1646
1647 __ bind(&try_arithmetic_simplification);
1653 __ cvttsd2si(exponent, double_exponent); 1648 __ cvttsd2si(exponent, double_exponent);
1654 // Skip to runtime if possibly NaN (indicated by the indefinite integer). 1649 // Skip to runtime if possibly NaN (indicated by the indefinite integer).
1655 __ cmpl(exponent, Immediate(0x80000000u)); 1650 __ cmpl(exponent, Immediate(0x80000000u));
1656 __ j(equal, &call_runtime); 1651 __ j(equal, &call_runtime);
1657 __ cvtlsi2sd(double_scratch, exponent);
1658 // Already ruled out NaNs for exponent.
1659 __ ucomisd(double_exponent, double_scratch);
1660 __ j(equal, &int_exponent);
1661 1652
1662 if (exponent_type_ == ON_STACK) { 1653 if (exponent_type_ == ON_STACK) {
1663 // Detect square root case. Crankshaft detects constant +/-0.5 at 1654 // Detect square root case. Crankshaft detects constant +/-0.5 at
1664 // compile time and uses DoMathPowHalf instead. We then skip this check 1655 // compile time and uses DoMathPowHalf instead. We then skip this check
1665 // for non-constant cases of +/-0.5 as these hardly occur. 1656 // for non-constant cases of +/-0.5 as these hardly occur.
1666 Label continue_sqrt, continue_rsqrt, not_plus_half; 1657 Label continue_sqrt, continue_rsqrt, not_plus_half;
1667 // Test for 0.5. 1658 // Test for 0.5.
1668 // Load double_scratch with 0.5. 1659 // Load double_scratch with 0.5.
1669 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64); 1660 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64);
1670 __ movq(double_scratch, scratch); 1661 __ movq(double_scratch, scratch);
(...skipping 4952 matching lines...) Expand 10 before | Expand all | Expand 10 after
6623 __ bind(&fast_elements_case); 6614 __ bind(&fast_elements_case);
6624 GenerateCase(masm, FAST_ELEMENTS); 6615 GenerateCase(masm, FAST_ELEMENTS);
6625 } 6616 }
6626 6617
6627 6618
6628 #undef __ 6619 #undef __
6629 6620
6630 } } // namespace v8::internal 6621 } } // namespace v8::internal
6631 6622
6632 #endif // V8_TARGET_ARCH_X64 6623 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698