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

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

Powered by Google App Engine
This is Rietveld 408576698