| OLD | NEW |
| 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 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 } | 695 } |
| 696 | 696 |
| 697 | 697 |
| 698 void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, | 698 void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, |
| 699 ExternalArrayType array_type) { | 699 ExternalArrayType array_type) { |
| 700 // ----------- S t a t e ------------- | 700 // ----------- S t a t e ------------- |
| 701 // -- rax : key | 701 // -- rax : key |
| 702 // -- rdx : receiver | 702 // -- rdx : receiver |
| 703 // -- rsp[0] : return address | 703 // -- rsp[0] : return address |
| 704 // ----------------------------------- | 704 // ----------------------------------- |
| 705 Label slow, failed_allocation; | 705 Label slow; |
| 706 | 706 |
| 707 // Check that the object isn't a smi. | 707 // Check that the object isn't a smi. |
| 708 __ JumpIfSmi(rdx, &slow); | 708 __ JumpIfSmi(rdx, &slow); |
| 709 | 709 |
| 710 // Check that the key is a smi. | 710 // Check that the key is a smi. |
| 711 __ JumpIfNotSmi(rax, &slow); | 711 __ JumpIfNotSmi(rax, &slow); |
| 712 | 712 |
| 713 // Check that the object is a JS object. | 713 // Check that the object is a JS object. |
| 714 __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); | 714 __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); |
| 715 __ j(not_equal, &slow); | 715 __ j(not_equal, &slow); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 case kExternalUnsignedShortArray: | 754 case kExternalUnsignedShortArray: |
| 755 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); | 755 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); |
| 756 break; | 756 break; |
| 757 case kExternalIntArray: | 757 case kExternalIntArray: |
| 758 __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0)); | 758 __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0)); |
| 759 break; | 759 break; |
| 760 case kExternalUnsignedIntArray: | 760 case kExternalUnsignedIntArray: |
| 761 __ movl(rcx, Operand(rbx, rcx, times_4, 0)); | 761 __ movl(rcx, Operand(rbx, rcx, times_4, 0)); |
| 762 break; | 762 break; |
| 763 case kExternalFloatArray: | 763 case kExternalFloatArray: |
| 764 __ fld_s(Operand(rbx, rcx, times_4, 0)); | 764 __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0)); |
| 765 break; | 765 break; |
| 766 default: | 766 default: |
| 767 UNREACHABLE(); | 767 UNREACHABLE(); |
| 768 break; | 768 break; |
| 769 } | 769 } |
| 770 | 770 |
| 771 // rax: index | 771 // rax: index |
| 772 // rdx: receiver | 772 // rdx: receiver |
| 773 // For integer array types: | 773 // For integer array types: |
| 774 // rcx: value | 774 // rcx: value |
| 775 // For floating-point array type: | 775 // For floating-point array type: |
| 776 // FP(0): value | 776 // xmm0: value as double. |
| 777 | 777 |
| 778 if (array_type == kExternalIntArray || | 778 ASSERT(kSmiValueSize == 32); |
| 779 array_type == kExternalUnsignedIntArray) { | 779 if (array_type == kExternalUnsignedIntArray) { |
| 780 // For the Int and UnsignedInt array types, we need to see whether | 780 // For the UnsignedInt array type, we need to see whether |
| 781 // the value can be represented in a Smi. If not, we need to convert | 781 // the value can be represented in a Smi. If not, we need to convert |
| 782 // it to a HeapNumber. | 782 // it to a HeapNumber. |
| 783 Label box_int; | 783 Label box_int; |
| 784 if (array_type == kExternalIntArray) { | 784 |
| 785 __ JumpIfNotValidSmiValue(rcx, &box_int); | 785 __ JumpIfUIntNotValidSmiValue(rcx, &box_int); |
| 786 } else { | |
| 787 ASSERT_EQ(array_type, kExternalUnsignedIntArray); | |
| 788 __ JumpIfUIntNotValidSmiValue(rcx, &box_int); | |
| 789 } | |
| 790 | 786 |
| 791 __ Integer32ToSmi(rax, rcx); | 787 __ Integer32ToSmi(rax, rcx); |
| 792 __ ret(0); | 788 __ ret(0); |
| 793 | 789 |
| 794 __ bind(&box_int); | 790 __ bind(&box_int); |
| 795 | 791 |
| 796 // Allocate a HeapNumber for the int and perform int-to-double | 792 // Allocate a HeapNumber for the int and perform int-to-double |
| 797 // conversion. | 793 // conversion. |
| 798 __ push(rcx); | 794 ASSERT(array_type == kExternalUnsignedIntArray); |
| 799 if (array_type == kExternalIntArray) { | 795 // The value is zero-extended since we loaded the value from memory |
| 800 __ fild_s(Operand(rsp, 0)); | 796 // with movl. |
| 801 } else { | 797 __ cvtqsi2sd(xmm0, rcx); |
| 802 ASSERT(array_type == kExternalUnsignedIntArray); | 798 |
| 803 // The value is zero-extended on the stack, because all pushes are | 799 __ AllocateHeapNumber(rcx, rbx, &slow); |
| 804 // 64-bit and we loaded the value from memory with movl. | |
| 805 __ fild_d(Operand(rsp, 0)); | |
| 806 } | |
| 807 __ pop(rcx); | |
| 808 // FP(0): value | |
| 809 __ AllocateHeapNumber(rcx, rbx, &failed_allocation); | |
| 810 // Set the value. | 800 // Set the value. |
| 801 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); |
| 811 __ movq(rax, rcx); | 802 __ movq(rax, rcx); |
| 812 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); | |
| 813 __ ret(0); | 803 __ ret(0); |
| 814 } else if (array_type == kExternalFloatArray) { | 804 } else if (array_type == kExternalFloatArray) { |
| 815 // For the floating-point array type, we need to always allocate a | 805 // For the floating-point array type, we need to always allocate a |
| 816 // HeapNumber. | 806 // HeapNumber. |
| 817 __ AllocateHeapNumber(rcx, rbx, &failed_allocation); | 807 __ AllocateHeapNumber(rcx, rbx, &slow); |
| 818 // Set the value. | 808 // Set the value. |
| 809 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); |
| 819 __ movq(rax, rcx); | 810 __ movq(rax, rcx); |
| 820 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); | |
| 821 __ ret(0); | 811 __ ret(0); |
| 822 } else { | 812 } else { |
| 823 __ Integer32ToSmi(rax, rcx); | 813 __ Integer32ToSmi(rax, rcx); |
| 824 __ ret(0); | 814 __ ret(0); |
| 825 } | 815 } |
| 826 | 816 |
| 827 // If we fail allocation of the HeapNumber, we still have a value on | |
| 828 // top of the FPU stack. Remove it. | |
| 829 __ bind(&failed_allocation); | |
| 830 __ ffree(); | |
| 831 __ fincstp(); | |
| 832 // Fall through to slow case. | |
| 833 | |
| 834 // Slow case: Jump to runtime. | 817 // Slow case: Jump to runtime. |
| 835 __ bind(&slow); | 818 __ bind(&slow); |
| 836 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); | 819 __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); |
| 837 GenerateRuntimeGetProperty(masm); | 820 GenerateRuntimeGetProperty(masm); |
| 838 } | 821 } |
| 839 | 822 |
| 840 | 823 |
| 841 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 824 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 842 // ----------- S t a t e ------------- | 825 // ----------- S t a t e ------------- |
| 843 // -- rax : key | 826 // -- rax : key |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 case kExternalShortArray: | 1092 case kExternalShortArray: |
| 1110 case kExternalUnsignedShortArray: | 1093 case kExternalUnsignedShortArray: |
| 1111 __ movw(Operand(rbx, rdi, times_2, 0), rdx); | 1094 __ movw(Operand(rbx, rdi, times_2, 0), rdx); |
| 1112 break; | 1095 break; |
| 1113 case kExternalIntArray: | 1096 case kExternalIntArray: |
| 1114 case kExternalUnsignedIntArray: | 1097 case kExternalUnsignedIntArray: |
| 1115 __ movl(Operand(rbx, rdi, times_4, 0), rdx); | 1098 __ movl(Operand(rbx, rdi, times_4, 0), rdx); |
| 1116 break; | 1099 break; |
| 1117 case kExternalFloatArray: | 1100 case kExternalFloatArray: |
| 1118 // Need to perform int-to-float conversion. | 1101 // Need to perform int-to-float conversion. |
| 1119 __ push(rdx); | 1102 __ cvtlsi2ss(xmm0, rdx); |
| 1120 __ fild_s(Operand(rsp, 0)); | 1103 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); |
| 1121 __ pop(rdx); | |
| 1122 __ fstp_s(Operand(rbx, rdi, times_4, 0)); | |
| 1123 break; | 1104 break; |
| 1124 default: | 1105 default: |
| 1125 UNREACHABLE(); | 1106 UNREACHABLE(); |
| 1126 break; | 1107 break; |
| 1127 } | 1108 } |
| 1128 __ ret(0); | 1109 __ ret(0); |
| 1129 | 1110 |
| 1130 __ bind(&check_heap_number); | 1111 __ bind(&check_heap_number); |
| 1131 // rax: value | 1112 // rax: value |
| 1132 // rcx: key (a smi) | 1113 // rcx: key (a smi) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1149 __ fstp_s(Operand(rbx, rdi, times_4, 0)); | 1130 __ fstp_s(Operand(rbx, rdi, times_4, 0)); |
| 1150 __ ret(0); | 1131 __ ret(0); |
| 1151 } else { | 1132 } else { |
| 1152 // Need to perform float-to-int conversion. | 1133 // Need to perform float-to-int conversion. |
| 1153 // Test the top of the FP stack for NaN. | 1134 // Test the top of the FP stack for NaN. |
| 1154 Label is_nan; | 1135 Label is_nan; |
| 1155 __ fucomi(0); | 1136 __ fucomi(0); |
| 1156 __ j(parity_even, &is_nan); | 1137 __ j(parity_even, &is_nan); |
| 1157 | 1138 |
| 1158 __ push(rdx); // Make room on the stack. Receiver is no longer needed. | 1139 __ push(rdx); // Make room on the stack. Receiver is no longer needed. |
| 1140 // TODO(lrn): If the rounding of this conversion is not deliberate, maybe |
| 1141 // switch to xmm registers. |
| 1159 __ fistp_d(Operand(rsp, 0)); | 1142 __ fistp_d(Operand(rsp, 0)); |
| 1160 __ pop(rdx); | 1143 __ pop(rdx); |
| 1161 // rdx: value (converted to an untagged integer) | 1144 // rdx: value (converted to an untagged integer) |
| 1162 // rdi: untagged index | 1145 // rdi: untagged index |
| 1163 // rbx: base pointer of external storage | 1146 // rbx: base pointer of external storage |
| 1164 switch (array_type) { | 1147 switch (array_type) { |
| 1165 case kExternalByteArray: | 1148 case kExternalByteArray: |
| 1166 case kExternalUnsignedByteArray: | 1149 case kExternalUnsignedByteArray: |
| 1167 __ movb(Operand(rbx, rdi, times_1, 0), rdx); | 1150 __ movb(Operand(rbx, rdi, times_1, 0), rdx); |
| 1168 break; | 1151 break; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1194 UNREACHABLE(); | 1177 UNREACHABLE(); |
| 1195 break; | 1178 break; |
| 1196 } | 1179 } |
| 1197 __ ret(0); | 1180 __ ret(0); |
| 1198 | 1181 |
| 1199 __ bind(&is_nan); | 1182 __ bind(&is_nan); |
| 1200 // rdi: untagged index | 1183 // rdi: untagged index |
| 1201 // rbx: base pointer of external storage | 1184 // rbx: base pointer of external storage |
| 1202 __ ffree(); | 1185 __ ffree(); |
| 1203 __ fincstp(); | 1186 __ fincstp(); |
| 1204 __ movq(rdx, Immediate(0)); | 1187 __ Set(rdx, 0); |
| 1205 switch (array_type) { | 1188 switch (array_type) { |
| 1206 case kExternalByteArray: | 1189 case kExternalByteArray: |
| 1207 case kExternalUnsignedByteArray: | 1190 case kExternalUnsignedByteArray: |
| 1208 __ movb(Operand(rbx, rdi, times_1, 0), rdx); | 1191 __ movb(Operand(rbx, rdi, times_1, 0), rdx); |
| 1209 break; | 1192 break; |
| 1210 case kExternalShortArray: | 1193 case kExternalShortArray: |
| 1211 case kExternalUnsignedShortArray: | 1194 case kExternalUnsignedShortArray: |
| 1212 __ movw(Operand(rbx, rdi, times_2, 0), rdx); | 1195 __ movw(Operand(rbx, rdi, times_2, 0), rdx); |
| 1213 break; | 1196 break; |
| 1214 case kExternalIntArray: | 1197 case kExternalIntArray: |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 GenerateMiss(masm); | 1799 GenerateMiss(masm); |
| 1817 } | 1800 } |
| 1818 | 1801 |
| 1819 | 1802 |
| 1820 #undef __ | 1803 #undef __ |
| 1821 | 1804 |
| 1822 | 1805 |
| 1823 } } // namespace v8::internal | 1806 } } // namespace v8::internal |
| 1824 | 1807 |
| 1825 #endif // V8_TARGET_ARCH_X64 | 1808 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |