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

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 22290005: Move ToI conversions to the MacroAssembler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address review and add test coverage for external array number truncation Created 7 years, 4 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 void MacroAssembler::ClampUint8(Register reg) { 154 void MacroAssembler::ClampUint8(Register reg) {
155 Label done; 155 Label done;
156 test(reg, Immediate(0xFFFFFF00)); 156 test(reg, Immediate(0xFFFFFF00));
157 j(zero, &done, Label::kNear); 157 j(zero, &done, Label::kNear);
158 setcc(negative, reg); // 1 if negative, 0 if positive. 158 setcc(negative, reg); // 1 if negative, 0 if positive.
159 dec_b(reg); // 0 if negative, 255 if positive. 159 dec_b(reg); // 0 if negative, 255 if positive.
160 bind(&done); 160 bind(&done);
161 } 161 }
162 162
163 163
164 void MacroAssembler::SlowTruncateToI(Register input_reg, Register result_reg,
165 int index) {
166 DoubleToIStub stub(input_reg, result_reg, index, true);
167 call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
168 }
169
170
171 void MacroAssembler::TruncateDoubleToI(
172 XMMRegister input_reg, Register result_reg) {
173 Label done;
174 cvttsd2si(result_reg, Operand(input_reg));
175 cmp(result_reg, 0x80000000u);
176 j(not_equal, &done, Label::kNear);
177
178 sub(esp, Immediate(kDoubleSize));
179 movdbl(MemOperand(esp, 0), input_reg);
180 SlowTruncateToI(esp, result_reg, 0);
181 add(esp, Immediate(kDoubleSize));
182 bind(&done);
183 }
184
185
186 void MacroAssembler::DoubleToI(XMMRegister input_reg, Register result_reg,
187 XMMRegister scratch, bool bailout_on_minus_zero,
188 Label* conversion_failed, Label::Distance dst) {
189 Label done;
190 cvttsd2si(result_reg, Operand(input_reg));
191 cvtsi2sd(scratch, Operand(result_reg));
192 ucomisd(scratch, input_reg);
193 j(not_equal, conversion_failed, dst);
194 j(parity_even, conversion_failed, dst); // NaN.
195 if (bailout_on_minus_zero) {
196 test(result_reg, Operand(result_reg));
197 j(not_zero, &done, Label::kNear);
198 movmskpd(result_reg, input_reg);
199 and_(result_reg, 1);
200 j(not_zero, conversion_failed, dst);
201 }
202 bind(&done);
203 }
204
205
206 void MacroAssembler::TruncateHeapNumberToI(Register input_reg,
207 Register result_reg) {
208 Label done, slow_case;
209
210 if (CpuFeatures::IsSupported(SSE3)) {
211 CpuFeatureScope scope(this, SSE3);
212 Label convert;
213 // Use more powerful conversion when sse3 is available.
214 // Load x87 register with heap number.
215 fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
216 // Get exponent alone and check for too-big exponent.
217 mov(result_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
218 and_(result_reg, HeapNumber::kExponentMask);
219 const uint32_t kTooBigExponent =
220 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
221 cmp(Operand(result_reg), Immediate(kTooBigExponent));
222 j(greater_equal, &slow_case, Label::kNear);
223
224 // Reserve space for 64 bit answer.
225 sub(Operand(esp), Immediate(kDoubleSize));
226 // Do conversion, which cannot fail because we checked the exponent.
227 fisttp_d(Operand(esp, 0));
228 mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
229 add(Operand(esp), Immediate(kDoubleSize));
230 jmp(&done, Label::kNear);
231
232 // Slow case.
233 bind(&slow_case);
234 if (input_reg.is(result_reg)) {
235 // Input is clobbered. Restore number from fpu stack
236 sub(Operand(esp), Immediate(kDoubleSize));
237 fstp_d(Operand(esp, 0));
238 SlowTruncateToI(esp, result_reg, 0);
239 add(esp, Immediate(kDoubleSize));
240 } else {
241 fstp(0);
242 SlowTruncateToI(input_reg, result_reg);
243 }
244 } else if (CpuFeatures::IsSupported(SSE2)) {
245 CpuFeatureScope scope(this, SSE2);
246 movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
247 cvttsd2si(result_reg, Operand(xmm0));
248 cmp(result_reg, 0x80000000u);
249 j(not_equal, &done, Label::kNear);
250 // Check if the input was 0x8000000 (kMinInt).
251 // If no, then we got an overflow and we deoptimize.
252 ExternalReference min_int = ExternalReference::address_of_min_int();
253 ucomisd(xmm0, Operand::StaticVariable(min_int));
254 j(not_equal, &slow_case, Label::kNear);
255 j(parity_even, &slow_case, Label::kNear); // NaN.
256 jmp(&done, Label::kNear);
257
258 // Slow case.
259 bind(&slow_case);
260 if (input_reg.is(result_reg)) {
261 // Input is clobbered. Restore number from double scratch.
262 sub(esp, Immediate(kDoubleSize));
263 movdbl(MemOperand(esp, 0), xmm0);
264 SlowTruncateToI(esp, result_reg, 0);
265 add(esp, Immediate(kDoubleSize));
266 } else {
267 SlowTruncateToI(input_reg, result_reg);
268 }
269 } else {
270 ASSERT(Serializer::enabled());
271 // TODO(olivf) If we ever hit this assert, it means that a DoubleToIStub is
272 // used in a snapshoted stub. In that case we should probably add a fast
273 // case here, which e.g. covers exponents < 31.
274 SlowTruncateToI(input_reg, result_reg);
275 }
276 bind(&done);
277 }
278
279
280 void MacroAssembler::TaggedToI(Register input_reg, Register result_reg,
281 XMMRegister temp, bool bailout_on_minus_zero, Label* bailout) {
danno 2013/08/13 13:04:20 perhaps a better name than bailout? lost_precision
282 Label done;
283
284 cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
285 isolate()->factory()->heap_number_map());
286 j(not_equal, bailout, Label::kNear);
287
288 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
289 ASSERT(!temp.is(no_xmm_reg));
290 CpuFeatureScope scope(this, SSE2);
291
292 movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
293 cvttsd2si(result_reg, Operand(xmm0));
294 cvtsi2sd(temp, Operand(result_reg));
295 ucomisd(xmm0, temp);
296 RecordComment("Deferred TaggedToI: lost precision");
297 j(not_equal, bailout, Label::kNear);
298 RecordComment("Deferred TaggedToI: NaN");
299 j(parity_even, bailout, Label::kNear);
300 if (bailout_on_minus_zero) {
301 test(result_reg, Operand(result_reg));
302 j(not_zero, &done, Label::kNear);
303 movmskpd(result_reg, xmm0);
304 and_(result_reg, 1);
305 RecordComment("Deferred TaggedToI: minus zero");
306 j(not_zero, bailout, Label::kNear);
307 }
308 } else {
309 // TODO(olivf) Converting a number on the fpu is actually quite slow. We
310 // should first try a fast conversion and then bailout to this slow case.
311 Label bailout_pop, zero_check;
312 sub(esp, Immediate(kPointerSize));
313 fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
314 if (bailout_on_minus_zero) fld(0);
315 fild_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
316 fist_s(MemOperand(esp, 0));
317 FCmp();
318 pop(result_reg);
319 j(not_equal, bailout_on_minus_zero ? &bailout_pop : bailout,
320 Label::kNear);
321 j(parity_even, bailout_on_minus_zero ? &bailout_pop : bailout,
322 Label::kNear); // NaN.
323 if (bailout_on_minus_zero) {
324 test(result_reg, Operand(result_reg));
325 j(zero, &zero_check, Label::kNear);
326 fstp(0);
327 jmp(&done, Label::kNear);
328 bind(&zero_check);
329 // To check for minus zero, we load the value again as float, and check
330 // if that is still 0.
331 sub(esp, Immediate(kPointerSize));
332 fstp_s(Operand(esp, 0));
333 pop(result_reg);
334 test(result_reg, Operand(result_reg));
335 j(zero, &done, Label::kNear);
336 jmp(bailout, Label::kNear);
337
338 bind(&bailout_pop);
339 fstp(0);
340 jmp(bailout, Label::kNear);
341 }
342 }
343 bind(&done);
344 }
345
346
347
164 static double kUint32Bias = 348 static double kUint32Bias =
165 static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1; 349 static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1;
166 350
167 351
168 void MacroAssembler::LoadUint32(XMMRegister dst, 352 void MacroAssembler::LoadUint32(XMMRegister dst,
169 Register src, 353 Register src,
170 XMMRegister scratch) { 354 XMMRegister scratch) {
171 Label done; 355 Label done;
172 cmp(src, Immediate(0)); 356 cmp(src, Immediate(0));
173 movdbl(scratch, 357 movdbl(scratch,
(...skipping 3013 matching lines...) Expand 10 before | Expand all | Expand 10 after
3187 j(greater, &no_memento_available); 3371 j(greater, &no_memento_available);
3188 cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), 3372 cmp(MemOperand(scratch_reg, -AllocationMemento::kSize),
3189 Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map()))); 3373 Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map())));
3190 bind(&no_memento_available); 3374 bind(&no_memento_available);
3191 } 3375 }
3192 3376
3193 3377
3194 } } // namespace v8::internal 3378 } } // namespace v8::internal
3195 3379
3196 #endif // V8_TARGET_ARCH_IA32 3380 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698