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 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1051 __ SmiUntag(ecx); | 1051 __ SmiUntag(ecx); |
1052 // Perform the operation. | 1052 // Perform the operation. |
1053 __ shr_cl(left); | 1053 __ shr_cl(left); |
1054 // Check that the *unsigned* result fits in a smi. | 1054 // Check that the *unsigned* result fits in a smi. |
1055 // Neither of the two high-order bits can be set: | 1055 // Neither of the two high-order bits can be set: |
1056 // - 0x80000000: high bit would be lost when smi tagging. | 1056 // - 0x80000000: high bit would be lost when smi tagging. |
1057 // - 0x40000000: this number would convert to negative when | 1057 // - 0x40000000: this number would convert to negative when |
1058 // Smi tagging these two cases can only happen with shifts | 1058 // Smi tagging these two cases can only happen with shifts |
1059 // by 0 or 1 when handed a valid smi. | 1059 // by 0 or 1 when handed a valid smi. |
1060 __ test(left, Immediate(0xc0000000)); | 1060 __ test(left, Immediate(0xc0000000)); |
1061 __ j(not_zero, slow); | 1061 __ j(not_zero, &use_fp_on_smis); |
1062 // Tag the result and store it in register eax. | 1062 // Tag the result and store it in register eax. |
1063 __ SmiTag(left); | 1063 __ SmiTag(left); |
1064 __ mov(eax, left); | 1064 __ mov(eax, left); |
1065 break; | 1065 break; |
1066 | 1066 |
1067 case Token::ADD: | 1067 case Token::ADD: |
1068 ASSERT(right.is(eax)); | 1068 ASSERT(right.is(eax)); |
1069 __ add(right, Operand(left)); // Addition is commutative. | 1069 __ add(right, Operand(left)); // Addition is commutative. |
1070 __ j(overflow, &use_fp_on_smis); | 1070 __ j(overflow, &use_fp_on_smis); |
1071 break; | 1071 break; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1187 __ mov(eax, edi); | 1187 __ mov(eax, edi); |
1188 break; | 1188 break; |
1189 default: | 1189 default: |
1190 // No other operators jump to use_fp_on_smis. | 1190 // No other operators jump to use_fp_on_smis. |
1191 break; | 1191 break; |
1192 } | 1192 } |
1193 __ jmp(¬_smis); | 1193 __ jmp(¬_smis); |
1194 } else { | 1194 } else { |
1195 ASSERT(allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS); | 1195 ASSERT(allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS); |
1196 switch (op_) { | 1196 switch (op_) { |
1197 case Token::SHL: { | 1197 case Token::SHL: |
1198 case Token::SHR: { | |
1198 Comment perform_float(masm, "-- Perform float operation on smis"); | 1199 Comment perform_float(masm, "-- Perform float operation on smis"); |
1199 __ bind(&use_fp_on_smis); | 1200 __ bind(&use_fp_on_smis); |
1200 // Result we want is in left == edx, so we can put the allocated heap | 1201 // Result we want is in left == edx, so we can put the allocated heap |
1201 // number in eax. | 1202 // number in eax. |
1202 __ AllocateHeapNumber(eax, ecx, ebx, slow); | 1203 __ AllocateHeapNumber(eax, ecx, ebx, slow); |
fschneider
2011/05/18 13:47:19
We should have a slow case for allocation failures
| |
1203 // Store the result in the HeapNumber and return. | 1204 // Store the result in the HeapNumber and return. |
1204 if (CpuFeatures::IsSupported(SSE2)) { | 1205 // It's OK to overwrite the arguments on the stack because we |
1205 CpuFeatures::Scope use_sse2(SSE2); | 1206 // are about to return. |
1206 __ cvtsi2sd(xmm0, Operand(left)); | 1207 if (op_ == Token::SHR) { |
1207 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 1208 __ mov(Operand(esp, 1 * kPointerSize), left); |
1209 __ mov(Operand(esp, 2 * kPointerSize), Immediate(0)); | |
1210 __ fild_d(Operand(esp, 1 * kPointerSize)); | |
1211 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | |
1208 } else { | 1212 } else { |
1209 // It's OK to overwrite the right argument on the stack because we | 1213 ASSERT_EQ(Token::SHL, op_); |
1210 // are about to return. | 1214 if (CpuFeatures::IsSupported(SSE2)) { |
1211 __ mov(Operand(esp, 1 * kPointerSize), left); | 1215 CpuFeatures::Scope use_sse2(SSE2); |
1212 __ fild_s(Operand(esp, 1 * kPointerSize)); | 1216 __ cvtsi2sd(xmm0, Operand(left)); |
1213 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 1217 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
1218 } else { | |
1219 __ mov(Operand(esp, 1 * kPointerSize), left); | |
1220 __ fild_s(Operand(esp, 1 * kPointerSize)); | |
1221 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | |
1222 } | |
1214 } | 1223 } |
1215 __ ret(2 * kPointerSize); | 1224 __ ret(2 * kPointerSize); |
1216 break; | 1225 break; |
1217 } | 1226 } |
1218 | 1227 |
1219 case Token::ADD: | 1228 case Token::ADD: |
1220 case Token::SUB: | 1229 case Token::SUB: |
1221 case Token::MUL: | 1230 case Token::MUL: |
1222 case Token::DIV: { | 1231 case Token::DIV: { |
1223 Comment perform_float(masm, "-- Perform float operation on smis"); | 1232 Comment perform_float(masm, "-- Perform float operation on smis"); |
1224 __ bind(&use_fp_on_smis); | 1233 __ bind(&use_fp_on_smis); |
1225 // Restore arguments to edx, eax. | 1234 // Restore arguments to edx, eax. |
1226 switch (op_) { | 1235 switch (op_) { |
(...skipping 4925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6152 __ Drop(1); | 6161 __ Drop(1); |
6153 __ ret(2 * kPointerSize); | 6162 __ ret(2 * kPointerSize); |
6154 } | 6163 } |
6155 | 6164 |
6156 | 6165 |
6157 #undef __ | 6166 #undef __ |
6158 | 6167 |
6159 } } // namespace v8::internal | 6168 } } // namespace v8::internal |
6160 | 6169 |
6161 #endif // V8_TARGET_ARCH_IA32 | 6170 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |