OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 3408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3419 case Token::kSUB: __ vsubd(result, left, right); break; | 3419 case Token::kSUB: __ vsubd(result, left, right); break; |
3420 case Token::kMUL: __ vmuld(result, left, right); break; | 3420 case Token::kMUL: __ vmuld(result, left, right); break; |
3421 case Token::kDIV: __ vdivd(result, left, right); break; | 3421 case Token::kDIV: __ vdivd(result, left, right); break; |
3422 default: UNREACHABLE(); | 3422 default: UNREACHABLE(); |
3423 } | 3423 } |
3424 } | 3424 } |
3425 | 3425 |
3426 | 3426 |
3427 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(Isolate* isolate, | 3427 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(Isolate* isolate, |
3428 bool opt) const { | 3428 bool opt) const { |
3429 UNIMPLEMENTED(); | 3429 const intptr_t kNumInputs = 1; |
3430 return NULL; | 3430 const intptr_t kNumTemps = 0; |
| 3431 LocationSummary* summary = new LocationSummary( |
| 3432 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3433 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3434 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3435 return summary; |
3431 } | 3436 } |
3432 | 3437 |
3433 | 3438 |
3434 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3439 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3435 UNIMPLEMENTED(); | 3440 const VRegister value = locs()->in(0).fpu_reg(); |
| 3441 const VRegister result = locs()->out(0).fpu_reg(); |
| 3442 |
| 3443 switch (op_kind()) { |
| 3444 case MethodRecognizer::kFloat32x4ShuffleX: |
| 3445 __ vinss(result, 0, value, 0); |
| 3446 __ fcvtds(result, result); |
| 3447 break; |
| 3448 case MethodRecognizer::kFloat32x4ShuffleY: |
| 3449 __ vinss(result, 0, value, 1); |
| 3450 __ fcvtds(result, result); |
| 3451 break; |
| 3452 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 3453 __ vinss(result, 0, value, 2); |
| 3454 __ fcvtds(result, result); |
| 3455 break; |
| 3456 case MethodRecognizer::kFloat32x4ShuffleW: |
| 3457 __ vinss(result, 0, value, 3); |
| 3458 __ fcvtds(result, result); |
| 3459 break; |
| 3460 case MethodRecognizer::kInt32x4Shuffle: |
| 3461 case MethodRecognizer::kFloat32x4Shuffle: |
| 3462 if (mask_ == 0x00) { |
| 3463 __ vdups(result, value, 0); |
| 3464 } else if (mask_ == 0x55) { |
| 3465 __ vdups(result, value, 1); |
| 3466 } else if (mask_ == 0xAA) { |
| 3467 __ vdups(result, value, 2); |
| 3468 } else if (mask_ == 0xFF) { |
| 3469 __ vdups(result, value, 3); |
| 3470 } else { |
| 3471 __ vinss(result, 0, value, mask_ & 0x3); |
| 3472 __ vinss(result, 1, value, (mask_ >> 2) & 0x3); |
| 3473 __ vinss(result, 2, value, (mask_ >> 4) & 0x3); |
| 3474 __ vinss(result, 3, value, (mask_ >> 6) & 0x3); |
| 3475 } |
| 3476 break; |
| 3477 default: UNREACHABLE(); |
| 3478 } |
3436 } | 3479 } |
3437 | 3480 |
3438 | 3481 |
3439 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(Isolate* isolate, | 3482 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(Isolate* isolate, |
3440 bool opt) const { | 3483 bool opt) const { |
3441 UNIMPLEMENTED(); | 3484 const intptr_t kNumInputs = 2; |
3442 return NULL; | 3485 const intptr_t kNumTemps = 0; |
| 3486 LocationSummary* summary = new LocationSummary( |
| 3487 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3488 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3489 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3490 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3491 return summary; |
3443 } | 3492 } |
3444 | 3493 |
3445 | 3494 |
3446 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3495 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3447 UNIMPLEMENTED(); | 3496 const VRegister left = locs()->in(0).fpu_reg(); |
| 3497 const VRegister right = locs()->in(1).fpu_reg(); |
| 3498 const VRegister result = locs()->out(0).fpu_reg(); |
| 3499 |
| 3500 switch (op_kind()) { |
| 3501 case MethodRecognizer::kFloat32x4ShuffleMix: |
| 3502 case MethodRecognizer::kInt32x4ShuffleMix: |
| 3503 __ vinss(result, 0, left, mask_ & 0x3); |
| 3504 __ vinss(result, 1, left, (mask_ >> 2) & 0x3); |
| 3505 __ vinss(result, 2, right, (mask_ >> 4) & 0x3); |
| 3506 __ vinss(result, 3, right, (mask_ >> 6) & 0x3); |
| 3507 break; |
| 3508 default: UNREACHABLE(); |
| 3509 } |
3448 } | 3510 } |
3449 | 3511 |
3450 | 3512 |
3451 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(Isolate* isolate, | 3513 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(Isolate* isolate, |
3452 bool opt) const { | 3514 bool opt) const { |
3453 UNIMPLEMENTED(); | 3515 const intptr_t kNumInputs = 1; |
3454 return NULL; | 3516 const intptr_t kNumTemps = 1; |
| 3517 LocationSummary* summary = new LocationSummary( |
| 3518 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3519 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3520 summary->set_temp(0, Location::RequiresRegister()); |
| 3521 summary->set_out(0, Location::RequiresRegister()); |
| 3522 return summary; |
3455 } | 3523 } |
3456 | 3524 |
3457 | 3525 |
3458 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3526 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3459 UNIMPLEMENTED(); | 3527 const VRegister value = locs()->in(0).fpu_reg(); |
| 3528 const Register out = locs()->out(0).reg(); |
| 3529 const Register temp = locs()->temp(0).reg(); |
| 3530 |
| 3531 // X lane. |
| 3532 __ vmovrs(out, value, 0); |
| 3533 __ Lsr(out, out, 31); |
| 3534 // Y lane. |
| 3535 __ vmovrs(temp, value, 1); |
| 3536 __ Lsr(temp, temp, 31); |
| 3537 __ orr(out, out, Operand(temp, LSL, 1)); |
| 3538 // Z lane. |
| 3539 __ vmovrs(temp, value, 2); |
| 3540 __ Lsr(temp, temp, 31); |
| 3541 __ orr(out, out, Operand(temp, LSL, 2)); |
| 3542 // W lane. |
| 3543 __ vmovrs(temp, value, 3); |
| 3544 __ Lsr(temp, temp, 31); |
| 3545 __ orr(out, out, Operand(temp, LSL, 3)); |
| 3546 // Tag. |
| 3547 __ SmiTag(out); |
3460 } | 3548 } |
3461 | 3549 |
3462 | 3550 |
3463 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( | 3551 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
3464 Isolate* isolate, bool opt) const { | 3552 Isolate* isolate, bool opt) const { |
3465 const intptr_t kNumInputs = 4; | 3553 const intptr_t kNumInputs = 4; |
3466 const intptr_t kNumTemps = 0; | 3554 const intptr_t kNumTemps = 0; |
3467 LocationSummary* summary = new(isolate) LocationSummary( | 3555 LocationSummary* summary = new(isolate) LocationSummary( |
3468 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3556 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3469 summary->set_in(0, Location::RequiresFpuRegister()); | 3557 summary->set_in(0, Location::RequiresFpuRegister()); |
3470 summary->set_in(1, Location::RequiresFpuRegister()); | 3558 summary->set_in(1, Location::RequiresFpuRegister()); |
3471 summary->set_in(2, Location::RequiresFpuRegister()); | 3559 summary->set_in(2, Location::RequiresFpuRegister()); |
3472 summary->set_in(3, Location::RequiresFpuRegister()); | 3560 summary->set_in(3, Location::RequiresFpuRegister()); |
3473 summary->set_out(0, Location::RequiresFpuRegister()); | 3561 summary->set_out(0, Location::RequiresFpuRegister()); |
3474 return summary; | 3562 return summary; |
3475 } | 3563 } |
3476 | 3564 |
3477 | 3565 |
3478 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3566 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3479 const VRegister v0 = locs()->in(0).fpu_reg(); | 3567 const VRegister v0 = locs()->in(0).fpu_reg(); |
3480 const VRegister v1 = locs()->in(1).fpu_reg(); | 3568 const VRegister v1 = locs()->in(1).fpu_reg(); |
3481 const VRegister v2 = locs()->in(2).fpu_reg(); | 3569 const VRegister v2 = locs()->in(2).fpu_reg(); |
3482 const VRegister v3 = locs()->in(3).fpu_reg(); | 3570 const VRegister v3 = locs()->in(3).fpu_reg(); |
3483 const VRegister r = locs()->out(0).fpu_reg(); | 3571 const VRegister r = locs()->out(0).fpu_reg(); |
3484 | 3572 |
3485 __ fcvtsd(v0, v0); | 3573 __ fcvtsd(VTMP, v0); |
3486 __ vinss(r, 0, v0, 0); | 3574 __ vinss(r, 0, VTMP, 0); |
3487 __ fcvtsd(v1, v1); | 3575 __ fcvtsd(VTMP, v1); |
3488 __ vinss(r, 1, v1, 1); | 3576 __ vinss(r, 1, VTMP, 0); |
3489 __ fcvtsd(v2, v2); | 3577 __ fcvtsd(VTMP, v2); |
3490 __ vinss(r, 2, v2, 2); | 3578 __ vinss(r, 2, VTMP, 0); |
3491 __ fcvtsd(v3, v3); | 3579 __ fcvtsd(VTMP, v3); |
3492 __ vinss(r, 3, v3, 3); | 3580 __ vinss(r, 3, VTMP, 0); |
3493 } | 3581 } |
3494 | 3582 |
3495 | 3583 |
3496 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(Isolate* isolate, | 3584 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(Isolate* isolate, |
3497 bool opt) const { | 3585 bool opt) const { |
3498 const intptr_t kNumInputs = 0; | 3586 const intptr_t kNumInputs = 0; |
3499 const intptr_t kNumTemps = 0; | 3587 const intptr_t kNumTemps = 0; |
3500 LocationSummary* summary = new(isolate) LocationSummary( | 3588 LocationSummary* summary = new(isolate) LocationSummary( |
3501 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3589 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3502 summary->set_out(0, Location::RequiresFpuRegister()); | 3590 summary->set_out(0, Location::RequiresFpuRegister()); |
3503 return summary; | 3591 return summary; |
3504 } | 3592 } |
3505 | 3593 |
3506 | 3594 |
3507 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3595 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3508 const VRegister v = locs()->out(0).fpu_reg(); | 3596 const VRegister v = locs()->out(0).fpu_reg(); |
3509 __ LoadDImmediate(v, 0.0, PP); | 3597 __ veor(v, v, v); |
3510 } | 3598 } |
3511 | 3599 |
3512 | 3600 |
3513 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(Isolate* isolate, | 3601 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(Isolate* isolate, |
3514 bool opt) const { | 3602 bool opt) const { |
3515 const intptr_t kNumInputs = 1; | 3603 const intptr_t kNumInputs = 1; |
3516 const intptr_t kNumTemps = 0; | 3604 const intptr_t kNumTemps = 0; |
3517 LocationSummary* summary = new(isolate) LocationSummary( | 3605 LocationSummary* summary = new(isolate) LocationSummary( |
3518 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3606 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3519 summary->set_in(0, Location::RequiresFpuRegister()); | 3607 summary->set_in(0, Location::RequiresFpuRegister()); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3594 __ vdups(result, VTMP, 0); | 3682 __ vdups(result, VTMP, 0); |
3595 __ vmuls(result, result, right); | 3683 __ vmuls(result, result, right); |
3596 break; | 3684 break; |
3597 default: UNREACHABLE(); | 3685 default: UNREACHABLE(); |
3598 } | 3686 } |
3599 } | 3687 } |
3600 | 3688 |
3601 | 3689 |
3602 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(Isolate* isolate, | 3690 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(Isolate* isolate, |
3603 bool opt) const { | 3691 bool opt) const { |
3604 UNIMPLEMENTED(); | 3692 const intptr_t kNumInputs = 1; |
3605 return NULL; | 3693 const intptr_t kNumTemps = 0; |
| 3694 LocationSummary* summary = new LocationSummary( |
| 3695 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3696 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3697 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3698 return summary; |
3606 } | 3699 } |
3607 | 3700 |
3608 | 3701 |
3609 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3702 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3610 UNIMPLEMENTED(); | 3703 const VRegister left = locs()->in(0).fpu_reg(); |
| 3704 const VRegister result = locs()->out(0).fpu_reg(); |
| 3705 |
| 3706 switch (op_kind()) { |
| 3707 case MethodRecognizer::kFloat32x4Negate: |
| 3708 __ vnegs(result, left); |
| 3709 break; |
| 3710 case MethodRecognizer::kFloat32x4Absolute: |
| 3711 __ vabss(result, left); |
| 3712 break; |
| 3713 default: UNREACHABLE(); |
| 3714 } |
3611 } | 3715 } |
3612 | 3716 |
3613 | 3717 |
3614 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(Isolate* isolate, | 3718 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(Isolate* isolate, |
3615 bool opt) const { | 3719 bool opt) const { |
3616 UNIMPLEMENTED(); | 3720 UNIMPLEMENTED(); |
3617 return NULL; | 3721 return NULL; |
3618 } | 3722 } |
3619 | 3723 |
3620 | 3724 |
3621 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3725 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3622 UNIMPLEMENTED(); | 3726 UNIMPLEMENTED(); |
3623 } | 3727 } |
3624 | 3728 |
3625 | 3729 |
3626 LocationSummary* Float32x4WithInstr::MakeLocationSummary(Isolate* isolate, | 3730 LocationSummary* Float32x4WithInstr::MakeLocationSummary(Isolate* isolate, |
3627 bool opt) const { | 3731 bool opt) const { |
3628 UNIMPLEMENTED(); | 3732 const intptr_t kNumInputs = 2; |
3629 return NULL; | 3733 const intptr_t kNumTemps = 0; |
| 3734 LocationSummary* summary = new LocationSummary( |
| 3735 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3736 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3737 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3738 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3739 return summary; |
3630 } | 3740 } |
3631 | 3741 |
3632 | 3742 |
3633 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3743 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3634 UNIMPLEMENTED(); | 3744 const VRegister replacement = locs()->in(0).fpu_reg(); |
| 3745 const VRegister value = locs()->in(1).fpu_reg(); |
| 3746 const VRegister result = locs()->out(0).fpu_reg(); |
| 3747 |
| 3748 __ fcvtsd(VTMP, replacement); |
| 3749 if (result != value) { |
| 3750 __ vmov(result, value); |
| 3751 } |
| 3752 |
| 3753 switch (op_kind()) { |
| 3754 case MethodRecognizer::kFloat32x4WithX: |
| 3755 __ vinss(result, 0, VTMP, 0); |
| 3756 break; |
| 3757 case MethodRecognizer::kFloat32x4WithY: |
| 3758 __ vinss(result, 1, VTMP, 0); |
| 3759 break; |
| 3760 case MethodRecognizer::kFloat32x4WithZ: |
| 3761 __ vinss(result, 2, VTMP, 0); |
| 3762 break; |
| 3763 case MethodRecognizer::kFloat32x4WithW: |
| 3764 __ vinss(result, 3, VTMP, 0); |
| 3765 break; |
| 3766 default: UNREACHABLE(); |
| 3767 } |
3635 } | 3768 } |
3636 | 3769 |
3637 | 3770 |
3638 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(Isolate* isolate, | 3771 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(Isolate* isolate, |
3639 bool opt) const { | 3772 bool opt) const { |
3640 UNIMPLEMENTED(); | 3773 const intptr_t kNumInputs = 1; |
3641 return NULL; | 3774 const intptr_t kNumTemps = 0; |
| 3775 LocationSummary* summary = new LocationSummary( |
| 3776 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3777 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3778 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3779 return summary; |
3642 } | 3780 } |
3643 | 3781 |
3644 | 3782 |
3645 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3783 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3646 UNIMPLEMENTED(); | 3784 const VRegister value = locs()->in(0).fpu_reg(); |
| 3785 const VRegister result = locs()->out(0).fpu_reg(); |
| 3786 |
| 3787 if (value != result) { |
| 3788 __ vmov(result, value); |
| 3789 } |
3647 } | 3790 } |
3648 | 3791 |
3649 | 3792 |
3650 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(Isolate* isolate, | 3793 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(Isolate* isolate, |
3651 bool opt) const { | 3794 bool opt) const { |
3652 const intptr_t kNumInputs = 1; | 3795 const intptr_t kNumInputs = 1; |
3653 const intptr_t kNumTemps = 0; | 3796 const intptr_t kNumTemps = 0; |
3654 LocationSummary* summary = new(isolate) LocationSummary( | 3797 LocationSummary* summary = new(isolate) LocationSummary( |
3655 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3798 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3656 summary->set_in(0, Location::RequiresFpuRegister()); | 3799 summary->set_in(0, Location::RequiresFpuRegister()); |
(...skipping 24 matching lines...) Expand all Loading... |
3681 const intptr_t kNumTemps = 0; | 3824 const intptr_t kNumTemps = 0; |
3682 LocationSummary* summary = new(isolate) LocationSummary( | 3825 LocationSummary* summary = new(isolate) LocationSummary( |
3683 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3826 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3684 summary->set_out(0, Location::RequiresFpuRegister()); | 3827 summary->set_out(0, Location::RequiresFpuRegister()); |
3685 return summary; | 3828 return summary; |
3686 } | 3829 } |
3687 | 3830 |
3688 | 3831 |
3689 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3832 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3690 const VRegister v = locs()->out(0).fpu_reg(); | 3833 const VRegister v = locs()->out(0).fpu_reg(); |
3691 __ LoadDImmediate(v, 0.0, PP); | 3834 __ veor(v, v, v); |
3692 } | 3835 } |
3693 | 3836 |
3694 | 3837 |
3695 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(Isolate* isolate, | 3838 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(Isolate* isolate, |
3696 bool opt) const { | 3839 bool opt) const { |
3697 const intptr_t kNumInputs = 1; | 3840 const intptr_t kNumInputs = 1; |
3698 const intptr_t kNumTemps = 0; | 3841 const intptr_t kNumTemps = 0; |
3699 LocationSummary* summary = new(isolate) LocationSummary( | 3842 LocationSummary* summary = new(isolate) LocationSummary( |
3700 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3843 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3701 summary->set_in(0, Location::RequiresFpuRegister()); | 3844 summary->set_in(0, Location::RequiresFpuRegister()); |
(...skipping 26 matching lines...) Expand all Loading... |
3728 const VRegister v0 = locs()->in(0).fpu_reg(); | 3871 const VRegister v0 = locs()->in(0).fpu_reg(); |
3729 const VRegister v1 = locs()->in(1).fpu_reg(); | 3872 const VRegister v1 = locs()->in(1).fpu_reg(); |
3730 const VRegister r = locs()->out(0).fpu_reg(); | 3873 const VRegister r = locs()->out(0).fpu_reg(); |
3731 __ vinsd(r, 0, v0, 0); | 3874 __ vinsd(r, 0, v0, 0); |
3732 __ vinsd(r, 0, v1, 0); | 3875 __ vinsd(r, 0, v1, 0); |
3733 } | 3876 } |
3734 | 3877 |
3735 | 3878 |
3736 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( | 3879 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( |
3737 Isolate* isolate, bool opt) const { | 3880 Isolate* isolate, bool opt) const { |
3738 UNIMPLEMENTED(); | 3881 const intptr_t kNumInputs = 1; |
3739 return NULL; | 3882 const intptr_t kNumTemps = 0; |
| 3883 LocationSummary* summary = new LocationSummary( |
| 3884 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3885 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3886 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3887 return summary; |
3740 } | 3888 } |
3741 | 3889 |
3742 | 3890 |
3743 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3891 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3744 UNIMPLEMENTED(); | 3892 const VRegister q = locs()->in(0).fpu_reg(); |
| 3893 const VRegister r = locs()->out(0).fpu_reg(); |
| 3894 |
| 3895 // Zero register. |
| 3896 __ veor(r, r, r); |
| 3897 // Set X lane. |
| 3898 __ vinsd(VTMP, 0, q, 0); |
| 3899 __ fcvtsd(VTMP, VTMP); |
| 3900 __ vinss(r, 0, VTMP, 0); |
| 3901 // Set Y lane. |
| 3902 __ vinsd(VTMP, 0, q, 1); |
| 3903 __ fcvtsd(VTMP, VTMP); |
| 3904 __ vinss(r, 1, VTMP, 0); |
3745 } | 3905 } |
3746 | 3906 |
3747 | 3907 |
3748 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( | 3908 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( |
3749 Isolate* isolate, bool opt) const { | 3909 Isolate* isolate, bool opt) const { |
3750 UNIMPLEMENTED(); | 3910 const intptr_t kNumInputs = 1; |
3751 return NULL; | 3911 const intptr_t kNumTemps = 0; |
| 3912 LocationSummary* summary = new LocationSummary( |
| 3913 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3914 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3915 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3916 return summary; |
3752 } | 3917 } |
3753 | 3918 |
3754 | 3919 |
3755 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3920 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3756 UNIMPLEMENTED(); | 3921 const VRegister q = locs()->in(0).fpu_reg(); |
| 3922 const VRegister r = locs()->out(0).fpu_reg(); |
| 3923 |
| 3924 // Set X. |
| 3925 __ vinss(VTMP, 0, q, 0); |
| 3926 __ fcvtds(VTMP, VTMP); |
| 3927 __ vinsd(r, 0, VTMP, 0); |
| 3928 // Set Y. |
| 3929 __ vinss(VTMP, 0, q, 1); |
| 3930 __ fcvtds(VTMP, VTMP); |
| 3931 __ vinsd(r, 1, VTMP, 0); |
3757 } | 3932 } |
3758 | 3933 |
3759 | 3934 |
3760 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(Isolate* isolate, | 3935 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(Isolate* isolate, |
3761 bool opt) const { | 3936 bool opt) const { |
3762 UNIMPLEMENTED(); | 3937 UNIMPLEMENTED(); |
3763 return NULL; | 3938 return NULL; |
3764 } | 3939 } |
3765 | 3940 |
3766 | 3941 |
3767 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3942 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3768 UNIMPLEMENTED(); | 3943 UNIMPLEMENTED(); |
3769 } | 3944 } |
3770 | 3945 |
3771 | 3946 |
3772 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(Isolate* isolate, | 3947 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(Isolate* isolate, |
3773 bool opt) const { | 3948 bool opt) const { |
3774 UNIMPLEMENTED(); | 3949 const intptr_t kNumInputs = 2; |
3775 return NULL; | 3950 const intptr_t kNumTemps = 0; |
| 3951 LocationSummary* summary = new LocationSummary( |
| 3952 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3953 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3954 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3955 summary->set_out(0, Location::SameAsFirstInput()); |
| 3956 return summary; |
3776 } | 3957 } |
3777 | 3958 |
3778 | 3959 |
3779 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3960 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3780 UNIMPLEMENTED(); | 3961 const VRegister left = locs()->in(0).fpu_reg(); |
| 3962 const VRegister right = locs()->in(1).fpu_reg(); |
| 3963 const VRegister out = locs()->out(0).fpu_reg(); |
| 3964 ASSERT(left == out); |
| 3965 |
| 3966 switch (op_kind()) { |
| 3967 case MethodRecognizer::kFloat64x2Scale: |
| 3968 __ vmuld(out, left, right); |
| 3969 break; |
| 3970 case MethodRecognizer::kFloat64x2WithX: |
| 3971 __ vinsd(out, 0, right, 0); |
| 3972 break; |
| 3973 case MethodRecognizer::kFloat64x2WithY: |
| 3974 __ vinsd(out, 1, right, 0); |
| 3975 break; |
| 3976 case MethodRecognizer::kFloat64x2Min: { |
| 3977 UNIMPLEMENTED(); |
| 3978 break; |
| 3979 } |
| 3980 case MethodRecognizer::kFloat64x2Max: { |
| 3981 UNIMPLEMENTED(); |
| 3982 break; |
| 3983 } |
| 3984 default: UNREACHABLE(); |
| 3985 } |
3781 } | 3986 } |
3782 | 3987 |
3783 | 3988 |
3784 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( | 3989 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
3785 Isolate* isolate, bool opt) const { | 3990 Isolate* isolate, bool opt) const { |
3786 UNIMPLEMENTED(); | 3991 const intptr_t kNumInputs = 4; |
3787 return NULL; | 3992 const intptr_t kNumTemps = 1; |
| 3993 LocationSummary* summary = new LocationSummary( |
| 3994 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3995 summary->set_in(0, Location::RequiresRegister()); |
| 3996 summary->set_in(1, Location::RequiresRegister()); |
| 3997 summary->set_in(2, Location::RequiresRegister()); |
| 3998 summary->set_in(3, Location::RequiresRegister()); |
| 3999 summary->set_temp(0, Location::RequiresRegister()); |
| 4000 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4001 return summary; |
3788 } | 4002 } |
3789 | 4003 |
3790 | 4004 |
3791 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4005 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3792 UNIMPLEMENTED(); | 4006 const Register v0 = locs()->in(0).reg(); |
| 4007 const Register v1 = locs()->in(1).reg(); |
| 4008 const Register v2 = locs()->in(2).reg(); |
| 4009 const Register v3 = locs()->in(3).reg(); |
| 4010 const Register temp = locs()->temp(0).reg(); |
| 4011 const VRegister result = locs()->out(0).fpu_reg(); |
| 4012 |
| 4013 __ veor(result, result, result); |
| 4014 __ LoadImmediate(temp, 0xffffffff, PP); |
| 4015 __ LoadObject(TMP2, Bool::True(), PP); |
| 4016 |
| 4017 // __ CompareObject(v0, Bool::True(), PP); |
| 4018 __ CompareRegisters(v0, TMP2); |
| 4019 __ csel(TMP, temp, ZR, EQ); |
| 4020 __ vinsw(result, 0, TMP); |
| 4021 |
| 4022 // __ CompareObject(v1, Bool::True(), PP); |
| 4023 __ CompareRegisters(v1, TMP2); |
| 4024 __ csel(TMP, temp, ZR, EQ); |
| 4025 __ vinsw(result, 1, TMP); |
| 4026 |
| 4027 // __ CompareObject(v2, Bool::True(), PP); |
| 4028 __ CompareRegisters(v2, TMP2); |
| 4029 __ csel(TMP, temp, ZR, EQ); |
| 4030 __ vinsw(result, 2, TMP); |
| 4031 |
| 4032 // __ CompareObject(v3, Bool::True(), PP); |
| 4033 __ CompareRegisters(v3, TMP2); |
| 4034 __ csel(TMP, temp, ZR, EQ); |
| 4035 __ vinsw(result, 3, TMP); |
3793 } | 4036 } |
3794 | 4037 |
3795 | 4038 |
3796 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(Isolate* isolate, | 4039 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(Isolate* isolate, |
3797 bool opt) const { | 4040 bool opt) const { |
3798 UNIMPLEMENTED(); | 4041 const intptr_t kNumInputs = 1; |
3799 return NULL; | 4042 const intptr_t kNumTemps = 0; |
| 4043 LocationSummary* summary = new LocationSummary( |
| 4044 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4045 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4046 summary->set_out(0, Location::RequiresRegister()); |
| 4047 return summary; |
3800 } | 4048 } |
3801 | 4049 |
3802 | 4050 |
3803 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4051 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3804 UNIMPLEMENTED(); | 4052 const VRegister value = locs()->in(0).fpu_reg(); |
| 4053 const Register result = locs()->out(0).reg(); |
| 4054 |
| 4055 switch (op_kind()) { |
| 4056 case MethodRecognizer::kInt32x4GetFlagX: |
| 4057 __ vmovrs(result, value, 0); |
| 4058 break; |
| 4059 case MethodRecognizer::kInt32x4GetFlagY: |
| 4060 __ vmovrs(result, value, 1); |
| 4061 break; |
| 4062 case MethodRecognizer::kInt32x4GetFlagZ: |
| 4063 __ vmovrs(result, value, 2); |
| 4064 break; |
| 4065 case MethodRecognizer::kInt32x4GetFlagW: |
| 4066 __ vmovrs(result, value, 3); |
| 4067 break; |
| 4068 default: UNREACHABLE(); |
| 4069 } |
| 4070 |
| 4071 __ tst(result, Operand(result)); |
| 4072 __ LoadObject(result, Bool::True(), PP); |
| 4073 __ LoadObject(TMP, Bool::False(), PP); |
| 4074 __ csel(result, TMP, result, EQ); |
3805 } | 4075 } |
3806 | 4076 |
3807 | 4077 |
3808 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(Isolate* isolate, | 4078 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(Isolate* isolate, |
3809 bool opt) const { | 4079 bool opt) const { |
3810 UNIMPLEMENTED(); | 4080 const intptr_t kNumInputs = 3; |
3811 return NULL; | 4081 const intptr_t kNumTemps = 1; |
| 4082 LocationSummary* summary = new LocationSummary( |
| 4083 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4084 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4085 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4086 summary->set_in(2, Location::RequiresFpuRegister()); |
| 4087 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 4088 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4089 return summary; |
3812 } | 4090 } |
3813 | 4091 |
3814 | 4092 |
3815 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4093 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3816 UNIMPLEMENTED(); | 4094 const VRegister mask = locs()->in(0).fpu_reg(); |
| 4095 const VRegister trueValue = locs()->in(1).fpu_reg(); |
| 4096 const VRegister falseValue = locs()->in(2).fpu_reg(); |
| 4097 const VRegister out = locs()->out(0).fpu_reg(); |
| 4098 const VRegister temp = locs()->temp(0).fpu_reg(); |
| 4099 |
| 4100 // Copy mask. |
| 4101 __ vmov(temp, mask); |
| 4102 // Invert it. |
| 4103 __ vnot(temp, temp); |
| 4104 // mask = mask & trueValue. |
| 4105 __ vand(mask, mask, trueValue); |
| 4106 // temp = temp & falseValue. |
| 4107 __ vand(temp, temp, falseValue); |
| 4108 // out = mask | temp. |
| 4109 __ vorr(out, mask, temp); |
3817 } | 4110 } |
3818 | 4111 |
3819 | 4112 |
3820 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(Isolate* isolate, | 4113 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(Isolate* isolate, |
3821 bool opt) const { | 4114 bool opt) const { |
3822 UNIMPLEMENTED(); | 4115 const intptr_t kNumInputs = 2; |
3823 return NULL; | 4116 const intptr_t kNumTemps = 0; |
| 4117 LocationSummary* summary = new LocationSummary( |
| 4118 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4119 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4120 summary->set_in(1, Location::RequiresRegister()); |
| 4121 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4122 return summary; |
3824 } | 4123 } |
3825 | 4124 |
3826 | 4125 |
3827 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4126 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3828 UNIMPLEMENTED(); | 4127 const VRegister mask = locs()->in(0).fpu_reg(); |
| 4128 const Register flag = locs()->in(1).reg(); |
| 4129 const VRegister result = locs()->out(0).fpu_reg(); |
| 4130 |
| 4131 if (result != mask) { |
| 4132 __ vmov(result, mask); |
| 4133 } |
| 4134 |
| 4135 __ CompareObject(flag, Bool::True(), PP); |
| 4136 __ LoadImmediate(TMP, 0xffffffff, PP); |
| 4137 __ csel(TMP, TMP, ZR, EQ); |
| 4138 switch (op_kind()) { |
| 4139 case MethodRecognizer::kInt32x4WithFlagX: |
| 4140 __ vinsw(result, 0, TMP); |
| 4141 break; |
| 4142 case MethodRecognizer::kInt32x4WithFlagY: |
| 4143 __ vinsw(result, 1, TMP); |
| 4144 break; |
| 4145 case MethodRecognizer::kInt32x4WithFlagZ: |
| 4146 __ vinsw(result, 2, TMP); |
| 4147 break; |
| 4148 case MethodRecognizer::kInt32x4WithFlagW: |
| 4149 __ vinsw(result, 3, TMP); |
| 4150 break; |
| 4151 default: UNREACHABLE(); |
| 4152 } |
3829 } | 4153 } |
3830 | 4154 |
3831 | 4155 |
3832 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 4156 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(Isolate* isolate, |
3833 bool opt) const { | 4157 bool opt) const { |
3834 UNIMPLEMENTED(); | 4158 const intptr_t kNumInputs = 1; |
3835 return NULL; | 4159 const intptr_t kNumTemps = 0; |
| 4160 LocationSummary* summary = new LocationSummary( |
| 4161 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4162 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4163 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4164 return summary; |
3836 } | 4165 } |
3837 | 4166 |
3838 | 4167 |
3839 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4168 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3840 UNIMPLEMENTED(); | 4169 const VRegister value = locs()->in(0).fpu_reg(); |
| 4170 const VRegister result = locs()->out(0).fpu_reg(); |
| 4171 |
| 4172 if (value != result) { |
| 4173 __ vmov(result, value); |
| 4174 } |
3841 } | 4175 } |
3842 | 4176 |
3843 | 4177 |
3844 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(Isolate* isolate, | 4178 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(Isolate* isolate, |
3845 bool opt) const { | 4179 bool opt) const { |
3846 UNIMPLEMENTED(); | 4180 const intptr_t kNumInputs = 2; |
3847 return NULL; | 4181 const intptr_t kNumTemps = 0; |
| 4182 LocationSummary* summary = new LocationSummary( |
| 4183 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4184 summary->set_in(0, Location::RequiresFpuRegister()); |
| 4185 summary->set_in(1, Location::RequiresFpuRegister()); |
| 4186 summary->set_out(0, Location::RequiresFpuRegister()); |
| 4187 return summary; |
3848 } | 4188 } |
3849 | 4189 |
3850 | 4190 |
3851 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4191 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3852 UNIMPLEMENTED(); | 4192 const VRegister left = locs()->in(0).fpu_reg(); |
3853 } | 4193 const VRegister right = locs()->in(1).fpu_reg(); |
3854 | 4194 const VRegister result = locs()->out(0).fpu_reg(); |
3855 | 4195 switch (op_kind()) { |
| 4196 case Token::kBIT_AND: __ vand(result, left, right); break; |
| 4197 case Token::kBIT_OR: __ vorr(result, left, right); break; |
| 4198 case Token::kBIT_XOR: __ veor(result, left, right); break; |
| 4199 case Token::kADD: __ vaddw(result, left, right); break; |
| 4200 case Token::kSUB: __ vsubw(result, left, right); break; |
| 4201 default: UNREACHABLE(); |
| 4202 } |
| 4203 } |
| 4204 |
| 4205 |
3856 LocationSummary* MathUnaryInstr::MakeLocationSummary(Isolate* isolate, | 4206 LocationSummary* MathUnaryInstr::MakeLocationSummary(Isolate* isolate, |
3857 bool opt) const { | 4207 bool opt) const { |
3858 if ((kind() == MathUnaryInstr::kSin) || (kind() == MathUnaryInstr::kCos)) { | 4208 if ((kind() == MathUnaryInstr::kSin) || (kind() == MathUnaryInstr::kCos)) { |
3859 const intptr_t kNumInputs = 1; | 4209 const intptr_t kNumInputs = 1; |
3860 const intptr_t kNumTemps = 0; | 4210 const intptr_t kNumTemps = 0; |
3861 LocationSummary* summary = new(isolate) LocationSummary( | 4211 LocationSummary* summary = new(isolate) LocationSummary( |
3862 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 4212 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
3863 summary->set_in(0, Location::FpuRegisterLocation(V0)); | 4213 summary->set_in(0, Location::FpuRegisterLocation(V0)); |
3864 summary->set_out(0, Location::FpuRegisterLocation(V0)); | 4214 summary->set_out(0, Location::FpuRegisterLocation(V0)); |
3865 return summary; | 4215 return summary; |
(...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4927 compiler->GenerateCall(token_pos(), | 5277 compiler->GenerateCall(token_pos(), |
4928 &label, | 5278 &label, |
4929 PcDescriptors::kOther, | 5279 PcDescriptors::kOther, |
4930 locs()); | 5280 locs()); |
4931 __ Drop(ArgumentCount()); // Discard arguments. | 5281 __ Drop(ArgumentCount()); // Discard arguments. |
4932 } | 5282 } |
4933 | 5283 |
4934 } // namespace dart | 5284 } // namespace dart |
4935 | 5285 |
4936 #endif // defined TARGET_ARCH_ARM64 | 5286 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |