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

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: add 2 asserts 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 void MacroAssembler::ClampUint8(Register reg) { 208 void MacroAssembler::ClampUint8(Register reg) {
209 Label done; 209 Label done;
210 test(reg, Immediate(0xFFFFFF00)); 210 test(reg, Immediate(0xFFFFFF00));
211 j(zero, &done, Label::kNear); 211 j(zero, &done, Label::kNear);
212 setcc(negative, reg); // 1 if negative, 0 if positive. 212 setcc(negative, reg); // 1 if negative, 0 if positive.
213 dec_b(reg); // 0 if negative, 255 if positive. 213 dec_b(reg); // 0 if negative, 255 if positive.
214 bind(&done); 214 bind(&done);
215 } 215 }
216 216
217 217
218 void MacroAssembler::SlowTruncateToI(Register input_reg, Register result_reg,
219 int index) {
220 DoubleToIStub stub(input_reg, result_reg, index, true);
221 call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
222 }
223
224
225 void MacroAssembler::TruncateDoubleToI(
226 XMMRegister input_reg, Register result_reg) {
227 Label done;
228 cvttsd2si(result_reg, Operand(input_reg));
229 cmp(result_reg, 0x80000000u);
230 j(not_equal, &done, Label::kNear);
231
232 sub(esp, Immediate(kDoubleSize));
233 movdbl(MemOperand(esp, 0), input_reg);
234 SlowTruncateToI(esp, result_reg, 0);
235 add(esp, Immediate(kDoubleSize));
236 bind(&done);
237 }
238
239
240 void MacroAssembler::TruncateX87TOSToI(Register result_reg) {
241 sub(esp, Immediate(kDoubleSize));
242 fst_d(MemOperand(esp, 0));
243 SlowTruncateToI(esp, result_reg, 0);
244 add(esp, Immediate(kDoubleSize));
245 }
246
247
248 void MacroAssembler::X87TOSToI(Register result_reg,
249 bool treat_minus_zero_as_zero,
250 Label* conversion_failed,
251 Label::Distance dst) {
252 Label done;
253 sub(esp, Immediate(kPointerSize));
254 fist_s(MemOperand(esp, 0));
255 fld(0);
256 fild_s(MemOperand(esp, 0));
257 pop(result_reg);
258 FCmp();
259 j(not_equal, conversion_failed, dst);
260 j(parity_even, conversion_failed, dst);
261 if (!treat_minus_zero_as_zero) {
262 test(result_reg, Operand(result_reg));
263 j(not_zero, &done, Label::kNear);
264 // To check for minus zero, we load the value again as float, and check
265 // if that is still 0.
266 sub(esp, Immediate(kPointerSize));
267 fst_s(MemOperand(esp, 0));
268 pop(result_reg);
269 test(result_reg, Operand(result_reg));
270 j(not_zero, conversion_failed, dst);
271 }
272 bind(&done);
273 }
274
275
276 void MacroAssembler::DoubleToI(XMMRegister input_reg, Register result_reg,
277 XMMRegister scratch, bool treat_minus_zero_as_zero,
278 Label* conversion_failed, Label::Distance dst) {
279 ASSERT(!input_reg.is(scratch));
280 Label done;
281 cvttsd2si(result_reg, Operand(input_reg));
282 cvtsi2sd(scratch, Operand(result_reg));
283 ucomisd(scratch, input_reg);
284 j(not_equal, conversion_failed, dst);
285 j(parity_even, conversion_failed, dst); // NaN.
286 if (!treat_minus_zero_as_zero) {
287 test(result_reg, Operand(result_reg));
288 j(not_zero, &done, Label::kNear);
289 movmskpd(result_reg, input_reg);
290 and_(result_reg, 1);
291 j(not_zero, conversion_failed, dst);
292 }
293 bind(&done);
294 }
295
296
297 void MacroAssembler::TruncateHeapNumberToI(Register input_reg,
298 Register result_reg) {
299 Label done, slow_case;
300
301 if (CpuFeatures::IsSupported(SSE3)) {
302 CpuFeatureScope scope(this, SSE3);
303 Label convert;
304 // Use more powerful conversion when sse3 is available.
305 // Load x87 register with heap number.
306 fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
307 // Get exponent alone and check for too-big exponent.
308 mov(result_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
309 and_(result_reg, HeapNumber::kExponentMask);
310 const uint32_t kTooBigExponent =
311 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
312 cmp(Operand(result_reg), Immediate(kTooBigExponent));
313 j(greater_equal, &slow_case, Label::kNear);
314
315 // Reserve space for 64 bit answer.
316 sub(Operand(esp), Immediate(kDoubleSize));
317 // Do conversion, which cannot fail because we checked the exponent.
318 fisttp_d(Operand(esp, 0));
319 mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
320 add(Operand(esp), Immediate(kDoubleSize));
321 jmp(&done, Label::kNear);
322
323 // Slow case.
324 bind(&slow_case);
325 if (input_reg.is(result_reg)) {
326 // Input is clobbered. Restore number from fpu stack
327 sub(Operand(esp), Immediate(kDoubleSize));
328 fstp_d(Operand(esp, 0));
329 SlowTruncateToI(esp, result_reg, 0);
330 add(esp, Immediate(kDoubleSize));
331 } else {
332 fstp(0);
333 SlowTruncateToI(input_reg, result_reg);
334 }
335 } else if (CpuFeatures::IsSupported(SSE2)) {
336 CpuFeatureScope scope(this, SSE2);
337 movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
338 cvttsd2si(result_reg, Operand(xmm0));
339 cmp(result_reg, 0x80000000u);
340 j(not_equal, &done, Label::kNear);
341 // Check if the input was 0x8000000 (kMinInt).
342 // If no, then we got an overflow and we deoptimize.
343 ExternalReference min_int = ExternalReference::address_of_min_int();
344 ucomisd(xmm0, Operand::StaticVariable(min_int));
345 j(not_equal, &slow_case, Label::kNear);
346 j(parity_even, &slow_case, Label::kNear); // NaN.
347 jmp(&done, Label::kNear);
348
349 // Slow case.
350 bind(&slow_case);
351 if (input_reg.is(result_reg)) {
352 // Input is clobbered. Restore number from double scratch.
353 sub(esp, Immediate(kDoubleSize));
354 movdbl(MemOperand(esp, 0), xmm0);
355 SlowTruncateToI(esp, result_reg, 0);
356 add(esp, Immediate(kDoubleSize));
357 } else {
358 SlowTruncateToI(input_reg, result_reg);
359 }
360 } else {
361 SlowTruncateToI(input_reg, result_reg);
362 }
363 bind(&done);
364 }
365
366
367 void MacroAssembler::TaggedToI(Register input_reg, Register result_reg,
368 XMMRegister temp, bool treat_minus_zero_as_zero, Label* lost_precision) {
369 Label done;
370 ASSERT(!temp.is(xmm0));
371
372 cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
373 isolate()->factory()->heap_number_map());
374 j(not_equal, lost_precision, Label::kNear);
375
376 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
377 ASSERT(!temp.is(no_xmm_reg));
378 CpuFeatureScope scope(this, SSE2);
379
380 movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
381 cvttsd2si(result_reg, Operand(xmm0));
382 cvtsi2sd(temp, Operand(result_reg));
383 ucomisd(xmm0, temp);
384 RecordComment("Deferred TaggedToI: lost precision");
385 j(not_equal, lost_precision, Label::kNear);
386 RecordComment("Deferred TaggedToI: NaN");
387 j(parity_even, lost_precision, Label::kNear);
388 if (!treat_minus_zero_as_zero) {
389 test(result_reg, Operand(result_reg));
390 j(not_zero, &done, Label::kNear);
391 movmskpd(result_reg, xmm0);
392 and_(result_reg, 1);
393 RecordComment("Deferred TaggedToI: minus zero");
394 j(not_zero, lost_precision, Label::kNear);
395 }
396 } else {
397 // TODO(olivf) Converting a number on the fpu is actually quite slow. We
398 // should first try a fast conversion and then bailout to this slow case.
399 Label lost_precision_pop, zero_check;
400 sub(esp, Immediate(kPointerSize));
401 fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
402 if (!treat_minus_zero_as_zero) fld(0);
403 fist_s(MemOperand(esp, 0));
404 fild_s(MemOperand(esp, 0));
405 FCmp();
406 pop(result_reg);
407 j(not_equal, !treat_minus_zero_as_zero
danno 2013/08/20 16:14:28 nit: Factor this label decision out into a variabl
oliv 2013/08/20 16:56:23 Done.
408 ? &lost_precision_pop : lost_precision, Label::kNear);
409 j(parity_even, !treat_minus_zero_as_zero
410 ? &lost_precision_pop : lost_precision, Label::kNear); // NaN.
411 if (!treat_minus_zero_as_zero) {
412 test(result_reg, Operand(result_reg));
413 j(zero, &zero_check, Label::kNear);
414 fstp(0);
415 jmp(&done, Label::kNear);
416 bind(&zero_check);
417 // To check for minus zero, we load the value again as float, and check
418 // if that is still 0.
419 sub(esp, Immediate(kPointerSize));
420 fstp_s(Operand(esp, 0));
421 pop(result_reg);
422 test(result_reg, Operand(result_reg));
423 j(zero, &done, Label::kNear);
424 jmp(lost_precision, Label::kNear);
425
426 bind(&lost_precision_pop);
427 fstp(0);
428 jmp(lost_precision, Label::kNear);
429 }
430 }
431 bind(&done);
432 }
433
434
435
218 static double kUint32Bias = 436 static double kUint32Bias =
219 static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1; 437 static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1;
220 438
221 439
222 void MacroAssembler::LoadUint32(XMMRegister dst, 440 void MacroAssembler::LoadUint32(XMMRegister dst,
223 Register src, 441 Register src,
224 XMMRegister scratch) { 442 XMMRegister scratch) {
225 Label done; 443 Label done;
226 cmp(src, Immediate(0)); 444 cmp(src, Immediate(0));
227 movdbl(scratch, 445 movdbl(scratch,
(...skipping 3009 matching lines...) Expand 10 before | Expand all | Expand 10 after
3237 j(greater, &no_memento_available); 3455 j(greater, &no_memento_available);
3238 cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), 3456 cmp(MemOperand(scratch_reg, -AllocationMemento::kSize),
3239 Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map()))); 3457 Immediate(Handle<Map>(isolate()->heap()->allocation_memento_map())));
3240 bind(&no_memento_available); 3458 bind(&no_memento_available);
3241 } 3459 }
3242 3460
3243 3461
3244 } } // namespace v8::internal 3462 } } // namespace v8::internal
3245 3463
3246 #endif // V8_TARGET_ARCH_IA32 3464 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698