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

Side by Side Diff: test/cctest/test-assembler-mips.cc

Issue 14113011: MIPS: Remove soft-float support. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 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/mips/stub-cache-mips.cc ('k') | no next file » | 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 double h; 270 double h;
271 double i; 271 double i;
272 } T; 272 } T;
273 T t; 273 T t;
274 274
275 // Create a function that accepts &t, and loads, manipulates, and stores 275 // Create a function that accepts &t, and loads, manipulates, and stores
276 // the doubles t.a ... t.f. 276 // the doubles t.a ... t.f.
277 MacroAssembler assm(isolate, NULL, 0); 277 MacroAssembler assm(isolate, NULL, 0);
278 Label L, C; 278 Label L, C;
279 279
280 if (CpuFeatures::IsSupported(FPU)) { 280 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
281 CpuFeatureScope scope(&assm, FPU); 281 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
282 __ add_d(f8, f4, f6);
283 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
282 284
283 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); 285 __ mov_d(f10, f8); // c
284 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) ); 286 __ neg_d(f12, f6); // -b
285 __ add_d(f8, f4, f6); 287 __ sub_d(f10, f10, f12);
286 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b. 288 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
287 289
288 __ mov_d(f10, f8); // c 290 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
289 __ neg_d(f12, f6); // -b
290 __ sub_d(f10, f10, f12);
291 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
292 291
293 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a. 292 __ li(t0, 120);
293 __ mtc1(t0, f14);
294 __ cvt_d_w(f14, f14); // f14 = 120.0.
295 __ mul_d(f10, f10, f14);
296 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
294 297
295 __ li(t0, 120); 298 __ div_d(f12, f10, f4);
296 __ mtc1(t0, f14); 299 __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44.
297 __ cvt_d_w(f14, f14); // f14 = 120.0.
298 __ mul_d(f10, f10, f14);
299 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
300 300
301 __ div_d(f12, f10, f4); 301 __ sqrt_d(f14, f12);
302 __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44. 302 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
303 303 // g = sqrt(f) = 10.97451593465515908537
304 __ sqrt_d(f14, f12);
305 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
306 // g = sqrt(f) = 10.97451593465515908537
307 304
308 if (kArchVariant == kMips32r2) { 305 if (kArchVariant == kMips32r2) {
309 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) ); 306 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
310 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) ); 307 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
311 __ madd_d(f14, f6, f4, f6); 308 __ madd_d(f14, f6, f4, f6);
312 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) ); 309 __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
313 } 310 }
314 311
315 __ jr(ra); 312 __ jr(ra);
316 __ nop(); 313 __ nop();
317 314
318 CodeDesc desc; 315 CodeDesc desc;
319 assm.GetCode(&desc); 316 assm.GetCode(&desc);
320 Object* code = HEAP->CreateCode( 317 Object* code = HEAP->CreateCode(
321 desc, 318 desc,
322 Code::ComputeFlags(Code::STUB), 319 Code::ComputeFlags(Code::STUB),
323 Handle<Code>())->ToObjectChecked(); 320 Handle<Code>())->ToObjectChecked();
324 CHECK(code->IsCode()); 321 CHECK(code->IsCode());
325 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); 322 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
326 t.a = 1.5e14; 323 t.a = 1.5e14;
327 t.b = 2.75e11; 324 t.b = 2.75e11;
328 t.c = 0.0; 325 t.c = 0.0;
329 t.d = 0.0; 326 t.d = 0.0;
330 t.e = 0.0; 327 t.e = 0.0;
331 t.f = 0.0; 328 t.f = 0.0;
332 t.h = 1.5; 329 t.h = 1.5;
333 t.i = 2.75; 330 t.i = 2.75;
334 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 331 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
335 USE(dummy); 332 USE(dummy);
336 CHECK_EQ(1.5e14, t.a); 333 CHECK_EQ(1.5e14, t.a);
337 CHECK_EQ(1.5e14, t.b); 334 CHECK_EQ(1.5e14, t.b);
338 CHECK_EQ(1.50275e14, t.c); 335 CHECK_EQ(1.50275e14, t.c);
339 CHECK_EQ(1.50550e14, t.d); 336 CHECK_EQ(1.50550e14, t.d);
340 CHECK_EQ(1.8066e16, t.e); 337 CHECK_EQ(1.8066e16, t.e);
341 CHECK_EQ(120.44, t.f); 338 CHECK_EQ(120.44, t.f);
342 CHECK_EQ(10.97451593465515908537, t.g); 339 CHECK_EQ(10.97451593465515908537, t.g);
343 CHECK_EQ(6.875, t.h); 340 CHECK_EQ(6.875, t.h);
344 }
345 } 341 }
346 342
347 343
348 TEST(MIPS4) { 344 TEST(MIPS4) {
349 // Test moves between floating point and integer registers. 345 // Test moves between floating point and integer registers.
350 CcTest::InitializeVM(); 346 CcTest::InitializeVM();
351 Isolate* isolate = Isolate::Current(); 347 Isolate* isolate = Isolate::Current();
352 HandleScope scope(isolate); 348 HandleScope scope(isolate);
353 349
354 typedef struct { 350 typedef struct {
355 double a; 351 double a;
356 double b; 352 double b;
357 double c; 353 double c;
358 } T; 354 } T;
359 T t; 355 T t;
360 356
361 Assembler assm(isolate, NULL, 0); 357 Assembler assm(isolate, NULL, 0);
362 Label L, C; 358 Label L, C;
363 359
364 if (CpuFeatures::IsSupported(FPU)) { 360 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
365 CpuFeatureScope scope(&assm, FPU); 361 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
366 362
367 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); 363 // Swap f4 and f6, by using four integer registers, t0-t3.
368 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) ); 364 __ mfc1(t0, f4);
365 __ mfc1(t1, f5);
366 __ mfc1(t2, f6);
367 __ mfc1(t3, f7);
369 368
370 // Swap f4 and f6, by using four integer registers, t0-t3. 369 __ mtc1(t0, f6);
371 __ mfc1(t0, f4); 370 __ mtc1(t1, f7);
372 __ mfc1(t1, f5); 371 __ mtc1(t2, f4);
373 __ mfc1(t2, f6); 372 __ mtc1(t3, f5);
374 __ mfc1(t3, f7);
375 373
376 __ mtc1(t0, f6); 374 // Store the swapped f4 and f5 back to memory.
377 __ mtc1(t1, f7); 375 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
378 __ mtc1(t2, f4); 376 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
379 __ mtc1(t3, f5);
380 377
381 // Store the swapped f4 and f5 back to memory. 378 __ jr(ra);
382 __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); 379 __ nop();
383 __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
384 380
385 __ jr(ra); 381 CodeDesc desc;
386 __ nop(); 382 assm.GetCode(&desc);
383 Object* code = HEAP->CreateCode(
384 desc,
385 Code::ComputeFlags(Code::STUB),
386 Handle<Code>())->ToObjectChecked();
387 CHECK(code->IsCode());
388 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
389 t.a = 1.5e22;
390 t.b = 2.75e11;
391 t.c = 17.17;
392 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
393 USE(dummy);
387 394
388 CodeDesc desc; 395 CHECK_EQ(2.75e11, t.a);
389 assm.GetCode(&desc); 396 CHECK_EQ(2.75e11, t.b);
390 Object* code = HEAP->CreateCode( 397 CHECK_EQ(1.5e22, t.c);
391 desc,
392 Code::ComputeFlags(Code::STUB),
393 Handle<Code>())->ToObjectChecked();
394 CHECK(code->IsCode());
395 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
396 t.a = 1.5e22;
397 t.b = 2.75e11;
398 t.c = 17.17;
399 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
400 USE(dummy);
401
402 CHECK_EQ(2.75e11, t.a);
403 CHECK_EQ(2.75e11, t.b);
404 CHECK_EQ(1.5e22, t.c);
405 }
406 } 398 }
407 399
408 400
409 TEST(MIPS5) { 401 TEST(MIPS5) {
410 // Test conversions between doubles and integers. 402 // Test conversions between doubles and integers.
411 CcTest::InitializeVM(); 403 CcTest::InitializeVM();
412 Isolate* isolate = Isolate::Current(); 404 Isolate* isolate = Isolate::Current();
413 HandleScope scope(isolate); 405 HandleScope scope(isolate);
414 406
415 typedef struct { 407 typedef struct {
416 double a; 408 double a;
417 double b; 409 double b;
418 int i; 410 int i;
419 int j; 411 int j;
420 } T; 412 } T;
421 T t; 413 T t;
422 414
423 Assembler assm(isolate, NULL, 0); 415 Assembler assm(isolate, NULL, 0);
424 Label L, C; 416 Label L, C;
425 417
426 if (CpuFeatures::IsSupported(FPU)) { 418 // Load all structure elements to registers.
427 CpuFeatureScope scope(&assm, FPU); 419 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
420 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
421 __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) );
422 __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
428 423
429 // Load all structure elements to registers. 424 // Convert double in f4 to int in element i.
430 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); 425 __ cvt_w_d(f8, f4);
431 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) ); 426 __ mfc1(t2, f8);
432 __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) ); 427 __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) );
433 __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
434 428
435 // Convert double in f4 to int in element i. 429 // Convert double in f6 to int in element j.
436 __ cvt_w_d(f8, f4); 430 __ cvt_w_d(f10, f6);
437 __ mfc1(t2, f8); 431 __ mfc1(t3, f10);
438 __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) ); 432 __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) );
439 433
440 // Convert double in f6 to int in element j. 434 // Convert int in original i (t0) to double in a.
441 __ cvt_w_d(f10, f6); 435 __ mtc1(t0, f12);
442 __ mfc1(t3, f10); 436 __ cvt_d_w(f0, f12);
443 __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) ); 437 __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
444 438
445 // Convert int in original i (t0) to double in a. 439 // Convert int in original j (t1) to double in b.
446 __ mtc1(t0, f12); 440 __ mtc1(t1, f14);
447 __ cvt_d_w(f0, f12); 441 __ cvt_d_w(f2, f14);
448 __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) ); 442 __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
449 443
450 // Convert int in original j (t1) to double in b. 444 __ jr(ra);
451 __ mtc1(t1, f14); 445 __ nop();
452 __ cvt_d_w(f2, f14);
453 __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
454 446
455 __ jr(ra); 447 CodeDesc desc;
456 __ nop(); 448 assm.GetCode(&desc);
449 Object* code = HEAP->CreateCode(
450 desc,
451 Code::ComputeFlags(Code::STUB),
452 Handle<Code>())->ToObjectChecked();
453 CHECK(code->IsCode());
454 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
455 t.a = 1.5e4;
456 t.b = 2.75e8;
457 t.i = 12345678;
458 t.j = -100000;
459 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
460 USE(dummy);
457 461
458 CodeDesc desc; 462 CHECK_EQ(12345678.0, t.a);
459 assm.GetCode(&desc); 463 CHECK_EQ(-100000.0, t.b);
460 Object* code = HEAP->CreateCode( 464 CHECK_EQ(15000, t.i);
461 desc, 465 CHECK_EQ(275000000, t.j);
462 Code::ComputeFlags(Code::STUB),
463 Handle<Code>())->ToObjectChecked();
464 CHECK(code->IsCode());
465 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
466 t.a = 1.5e4;
467 t.b = 2.75e8;
468 t.i = 12345678;
469 t.j = -100000;
470 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
471 USE(dummy);
472
473 CHECK_EQ(12345678.0, t.a);
474 CHECK_EQ(-100000.0, t.b);
475 CHECK_EQ(15000, t.i);
476 CHECK_EQ(275000000, t.j);
477 }
478 } 466 }
479 467
480 468
481 TEST(MIPS6) { 469 TEST(MIPS6) {
482 // Test simple memory loads and stores. 470 // Test simple memory loads and stores.
483 CcTest::InitializeVM(); 471 CcTest::InitializeVM();
484 Isolate* isolate = Isolate::Current(); 472 Isolate* isolate = Isolate::Current();
485 HandleScope scope(isolate); 473 HandleScope scope(isolate);
486 474
487 typedef struct { 475 typedef struct {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 double f; 554 double f;
567 int32_t result; 555 int32_t result;
568 } T; 556 } T;
569 T t; 557 T t;
570 558
571 // Create a function that accepts &t, and loads, manipulates, and stores 559 // Create a function that accepts &t, and loads, manipulates, and stores
572 // the doubles t.a ... t.f. 560 // the doubles t.a ... t.f.
573 MacroAssembler assm(isolate, NULL, 0); 561 MacroAssembler assm(isolate, NULL, 0);
574 Label neither_is_nan, less_than, outa_here; 562 Label neither_is_nan, less_than, outa_here;
575 563
576 if (CpuFeatures::IsSupported(FPU)) { 564 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
577 CpuFeatureScope scope(&assm, FPU); 565 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
566 __ c(UN, D, f4, f6);
567 __ bc1f(&neither_is_nan);
568 __ nop();
569 __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
570 __ Branch(&outa_here);
578 571
579 __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) ); 572 __ bind(&neither_is_nan);
580 __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
581 __ c(UN, D, f4, f6);
582 __ bc1f(&neither_is_nan);
583 __ nop();
584 __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
585 __ Branch(&outa_here);
586 573
587 __ bind(&neither_is_nan); 574 if (kArchVariant == kLoongson) {
575 __ c(OLT, D, f6, f4);
576 __ bc1t(&less_than);
577 } else {
578 __ c(OLT, D, f6, f4, 2);
579 __ bc1t(&less_than, 2);
580 }
581 __ nop();
582 __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
583 __ Branch(&outa_here);
588 584
589 if (kArchVariant == kLoongson) { 585 __ bind(&less_than);
590 __ c(OLT, D, f6, f4); 586 __ Addu(t0, zero_reg, Operand(1));
591 __ bc1t(&less_than); 587 __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
592 } else {
593 __ c(OLT, D, f6, f4, 2);
594 __ bc1t(&less_than, 2);
595 }
596 __ nop();
597 __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
598 __ Branch(&outa_here);
599
600 __ bind(&less_than);
601 __ Addu(t0, zero_reg, Operand(1));
602 __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
603 588
604 589
605 // This test-case should have additional tests. 590 // This test-case should have additional tests.
606 591
607 __ bind(&outa_here); 592 __ bind(&outa_here);
608 593
609 __ jr(ra); 594 __ jr(ra);
610 __ nop(); 595 __ nop();
611 596
612 CodeDesc desc; 597 CodeDesc desc;
613 assm.GetCode(&desc); 598 assm.GetCode(&desc);
614 Object* code = HEAP->CreateCode( 599 Object* code = HEAP->CreateCode(
615 desc, 600 desc,
616 Code::ComputeFlags(Code::STUB), 601 Code::ComputeFlags(Code::STUB),
617 Handle<Code>())->ToObjectChecked(); 602 Handle<Code>())->ToObjectChecked();
618 CHECK(code->IsCode()); 603 CHECK(code->IsCode());
619 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); 604 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
620 t.a = 1.5e14; 605 t.a = 1.5e14;
621 t.b = 2.75e11; 606 t.b = 2.75e11;
622 t.c = 2.0; 607 t.c = 2.0;
623 t.d = -4.0; 608 t.d = -4.0;
624 t.e = 0.0; 609 t.e = 0.0;
625 t.f = 0.0; 610 t.f = 0.0;
626 t.result = 0; 611 t.result = 0;
627 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 612 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
628 USE(dummy); 613 USE(dummy);
629 CHECK_EQ(1.5e14, t.a); 614 CHECK_EQ(1.5e14, t.a);
630 CHECK_EQ(2.75e11, t.b); 615 CHECK_EQ(2.75e11, t.b);
631 CHECK_EQ(1, t.result); 616 CHECK_EQ(1, t.result);
632 }
633 } 617 }
634 618
635 619
636 TEST(MIPS8) { 620 TEST(MIPS8) {
637 // Test ROTR and ROTRV instructions. 621 // Test ROTR and ROTRV instructions.
638 CcTest::InitializeVM(); 622 CcTest::InitializeVM();
639 Isolate* isolate = Isolate::Current(); 623 Isolate* isolate = Isolate::Current();
640 HandleScope scope(isolate); 624 HandleScope scope(isolate);
641 625
642 typedef struct { 626 typedef struct {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 int32_t long_hi; 766 int32_t long_hi;
783 int32_t long_lo; 767 int32_t long_lo;
784 int32_t b_long_hi; 768 int32_t b_long_hi;
785 int32_t b_long_lo; 769 int32_t b_long_lo;
786 } T; 770 } T;
787 T t; 771 T t;
788 772
789 Assembler assm(isolate, NULL, 0); 773 Assembler assm(isolate, NULL, 0);
790 Label L, C; 774 Label L, C;
791 775
792 if (CpuFeatures::IsSupported(FPU) && kArchVariant == kMips32r2) { 776 if (kArchVariant == kMips32r2) {
793 CpuFeatureScope scope(&assm, FPU);
794
795 // Load all structure elements to registers. 777 // Load all structure elements to registers.
796 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a))); 778 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
797 779
798 // Save the raw bits of the double. 780 // Save the raw bits of the double.
799 __ mfc1(t0, f0); 781 __ mfc1(t0, f0);
800 __ mfc1(t1, f1); 782 __ mfc1(t1, f1);
801 __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant))); 783 __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
802 __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp))); 784 __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
803 785
804 // Convert double in f0 to long, save hi/lo parts. 786 // Convert double in f0 to long, save hi/lo parts.
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 double cvt_small_out; 1072 double cvt_small_out;
1091 uint32_t trunc_big_out; 1073 uint32_t trunc_big_out;
1092 uint32_t trunc_small_out; 1074 uint32_t trunc_small_out;
1093 uint32_t cvt_big_in; 1075 uint32_t cvt_big_in;
1094 uint32_t cvt_small_in; 1076 uint32_t cvt_small_in;
1095 } T; 1077 } T;
1096 T t; 1078 T t;
1097 1079
1098 MacroAssembler assm(isolate, NULL, 0); 1080 MacroAssembler assm(isolate, NULL, 0);
1099 1081
1100 if (CpuFeatures::IsSupported(FPU)) { 1082 __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
1101 CpuFeatureScope scope(&assm, FPU); 1083 __ Cvt_d_uw(f10, t0, f22);
1084 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
1102 1085
1103 __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in))); 1086 __ Trunc_uw_d(f10, f10, f22);
1104 __ Cvt_d_uw(f10, t0, f22); 1087 __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
1105 __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
1106 1088
1107 __ Trunc_uw_d(f10, f10, f22); 1089 __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
1108 __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out))); 1090 __ Cvt_d_uw(f8, t0, f22);
1091 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
1109 1092
1110 __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in))); 1093 __ Trunc_uw_d(f8, f8, f22);
1111 __ Cvt_d_uw(f8, t0, f22); 1094 __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
1112 __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
1113 1095
1114 __ Trunc_uw_d(f8, f8, f22); 1096 __ jr(ra);
1115 __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out))); 1097 __ nop();
1116 1098
1117 __ jr(ra); 1099 CodeDesc desc;
1118 __ nop(); 1100 assm.GetCode(&desc);
1101 Object* code = HEAP->CreateCode(
1102 desc,
1103 Code::ComputeFlags(Code::STUB),
1104 Handle<Code>())->ToObjectChecked();
1105 CHECK(code->IsCode());
1106 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
1119 1107
1120 CodeDesc desc; 1108 t.cvt_big_in = 0xFFFFFFFF;
1121 assm.GetCode(&desc); 1109 t.cvt_small_in = 333;
1122 Object* code = HEAP->CreateCode(
1123 desc,
1124 Code::ComputeFlags(Code::STUB),
1125 Handle<Code>())->ToObjectChecked();
1126 CHECK(code->IsCode());
1127 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
1128 1110
1129 t.cvt_big_in = 0xFFFFFFFF; 1111 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1130 t.cvt_small_in = 333; 1112 USE(dummy);
1131 1113
1132 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); 1114 CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
1133 USE(dummy); 1115 CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
1134 1116
1135 CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in)); 1117 CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
1136 CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in)); 1118 CHECK_EQ(static_cast<int>(t.trunc_small_out),
1137 1119 static_cast<int>(t.cvt_small_in));
1138 CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
1139 CHECK_EQ(static_cast<int>(t.trunc_small_out),
1140 static_cast<int>(t.cvt_small_in));
1141 }
1142 } 1120 }
1143 1121
1144 1122
1145 TEST(MIPS14) { 1123 TEST(MIPS14) {
1146 // Test round, floor, ceil, trunc, cvt. 1124 // Test round, floor, ceil, trunc, cvt.
1147 CcTest::InitializeVM(); 1125 CcTest::InitializeVM();
1148 Isolate* isolate = Isolate::Current(); 1126 Isolate* isolate = Isolate::Current();
1149 HandleScope scope(isolate); 1127 HandleScope scope(isolate);
1150 1128
1151 #define ROUND_STRUCT_ELEMENT(x) \ 1129 #define ROUND_STRUCT_ELEMENT(x) \
(...skipping 22 matching lines...) Expand all
1174 ROUND_STRUCT_ELEMENT(ceil) 1152 ROUND_STRUCT_ELEMENT(ceil)
1175 ROUND_STRUCT_ELEMENT(trunc) 1153 ROUND_STRUCT_ELEMENT(trunc)
1176 ROUND_STRUCT_ELEMENT(cvt) 1154 ROUND_STRUCT_ELEMENT(cvt)
1177 } T; 1155 } T;
1178 T t; 1156 T t;
1179 1157
1180 #undef ROUND_STRUCT_ELEMENT 1158 #undef ROUND_STRUCT_ELEMENT
1181 1159
1182 MacroAssembler assm(isolate, NULL, 0); 1160 MacroAssembler assm(isolate, NULL, 0);
1183 1161
1184 if (CpuFeatures::IsSupported(FPU)) { 1162 // Save FCSR.
1185 CpuFeatureScope scope(&assm, FPU); 1163 __ cfc1(a1, FCSR);
1164 // Disable FPU exceptions.
1165 __ ctc1(zero_reg, FCSR);
1166 #define RUN_ROUND_TEST(x) \
1167 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
1168 __ x##_w_d(f0, f0); \
1169 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
1170 \
1171 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
1172 __ x##_w_d(f0, f0); \
1173 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
1174 \
1175 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
1176 __ x##_w_d(f0, f0); \
1177 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
1178 \
1179 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
1180 __ x##_w_d(f0, f0); \
1181 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
1182 \
1183 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
1184 __ ctc1(zero_reg, FCSR); \
1185 __ x##_w_d(f0, f0); \
1186 __ cfc1(a2, FCSR); \
1187 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
1188 \
1189 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
1190 __ ctc1(zero_reg, FCSR); \
1191 __ x##_w_d(f0, f0); \
1192 __ cfc1(a2, FCSR); \
1193 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
1194 \
1195 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
1196 __ ctc1(zero_reg, FCSR); \
1197 __ x##_w_d(f0, f0); \
1198 __ cfc1(a2, FCSR); \
1199 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
1200 \
1201 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
1202 __ ctc1(zero_reg, FCSR); \
1203 __ x##_w_d(f0, f0); \
1204 __ cfc1(a2, FCSR); \
1205 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
1206 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
1186 1207
1187 // Save FCSR. 1208 RUN_ROUND_TEST(round)
1188 __ cfc1(a1, FCSR); 1209 RUN_ROUND_TEST(floor)
1189 // Disable FPU exceptions. 1210 RUN_ROUND_TEST(ceil)
1190 __ ctc1(zero_reg, FCSR); 1211 RUN_ROUND_TEST(trunc)
1191 #define RUN_ROUND_TEST(x) \ 1212 RUN_ROUND_TEST(cvt)
1192 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
1193 __ x##_w_d(f0, f0); \
1194 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
1195 \
1196 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
1197 __ x##_w_d(f0, f0); \
1198 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
1199 \
1200 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
1201 __ x##_w_d(f0, f0); \
1202 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
1203 \
1204 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
1205 __ x##_w_d(f0, f0); \
1206 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
1207 \
1208 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
1209 __ ctc1(zero_reg, FCSR); \
1210 __ x##_w_d(f0, f0); \
1211 __ cfc1(a2, FCSR); \
1212 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
1213 \
1214 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
1215 __ ctc1(zero_reg, FCSR); \
1216 __ x##_w_d(f0, f0); \
1217 __ cfc1(a2, FCSR); \
1218 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
1219 \
1220 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
1221 __ ctc1(zero_reg, FCSR); \
1222 __ x##_w_d(f0, f0); \
1223 __ cfc1(a2, FCSR); \
1224 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
1225 \
1226 __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
1227 __ ctc1(zero_reg, FCSR); \
1228 __ x##_w_d(f0, f0); \
1229 __ cfc1(a2, FCSR); \
1230 __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
1231 __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
1232 1213
1233 RUN_ROUND_TEST(round) 1214 // Restore FCSR.
1234 RUN_ROUND_TEST(floor) 1215 __ ctc1(a1, FCSR);
1235 RUN_ROUND_TEST(ceil)
1236 RUN_ROUND_TEST(trunc)
1237 RUN_ROUND_TEST(cvt)
1238 1216
1239 // Restore FCSR. 1217 __ jr(ra);
1240 __ ctc1(a1, FCSR); 1218 __ nop();
1241 1219
1242 __ jr(ra); 1220 CodeDesc desc;
1243 __ nop(); 1221 assm.GetCode(&desc);
1222 Object* code = HEAP->CreateCode(
1223 desc,
1224 Code::ComputeFlags(Code::STUB),
1225 Handle<Code>())->ToObjectChecked();
1226 CHECK(code->IsCode());
1227 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
1244 1228
1245 CodeDesc desc; 1229 t.round_up_in = 123.51;
1246 assm.GetCode(&desc); 1230 t.round_down_in = 123.49;
1247 Object* code = HEAP->CreateCode( 1231 t.neg_round_up_in = -123.5;
1248 desc, 1232 t.neg_round_down_in = -123.49;
1249 Code::ComputeFlags(Code::STUB), 1233 t.err1_in = 123.51;
1250 Handle<Code>())->ToObjectChecked(); 1234 t.err2_in = 1;
1251 CHECK(code->IsCode()); 1235 t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
1252 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); 1236 t.err4_in = NAN;
1253 1237
1254 t.round_up_in = 123.51; 1238 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1255 t.round_down_in = 123.49; 1239 USE(dummy);
1256 t.neg_round_up_in = -123.5;
1257 t.neg_round_down_in = -123.49;
1258 t.err1_in = 123.51;
1259 t.err2_in = 1;
1260 t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
1261 t.err4_in = NAN;
1262
1263 Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
1264 USE(dummy);
1265 1240
1266 #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask)) 1241 #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
1267 #define CHECK_ROUND_RESULT(type) \ 1242 #define CHECK_ROUND_RESULT(type) \
1268 CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \ 1243 CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
1269 CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \ 1244 CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
1270 CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \ 1245 CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
1271 CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \ 1246 CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
1272 CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result); 1247 CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result);
1273 1248
1274 CHECK_ROUND_RESULT(round); 1249 CHECK_ROUND_RESULT(round);
1275 CHECK_ROUND_RESULT(floor); 1250 CHECK_ROUND_RESULT(floor);
1276 CHECK_ROUND_RESULT(ceil); 1251 CHECK_ROUND_RESULT(ceil);
1277 CHECK_ROUND_RESULT(cvt); 1252 CHECK_ROUND_RESULT(cvt);
1278 }
1279 } 1253 }
1280 1254
1281 1255
1282 TEST(MIPS15) { 1256 TEST(MIPS15) {
1283 // Test chaining of label usages within instructions (issue 1644). 1257 // Test chaining of label usages within instructions (issue 1644).
1284 CcTest::InitializeVM(); 1258 CcTest::InitializeVM();
1285 Isolate* isolate = Isolate::Current(); 1259 Isolate* isolate = Isolate::Current();
1286 HandleScope scope(isolate); 1260 HandleScope scope(isolate);
1287 Assembler assm(isolate, NULL, 0); 1261 Assembler assm(isolate, NULL, 0);
1288 1262
1289 Label target; 1263 Label target;
1290 __ beq(v0, v1, &target); 1264 __ beq(v0, v1, &target);
1291 __ nop(); 1265 __ nop();
1292 __ bne(v0, v1, &target); 1266 __ bne(v0, v1, &target);
1293 __ nop(); 1267 __ nop();
1294 __ bind(&target); 1268 __ bind(&target);
1295 __ nop(); 1269 __ nop();
1296 } 1270 }
1297 1271
1298 #undef __ 1272 #undef __
OLDNEW
« no previous file with comments | « src/mips/stub-cache-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698