| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 2701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2712 __ TryAllocate(compiler->float32x4_class(), | 2712 __ TryAllocate(compiler->float32x4_class(), |
| 2713 slow_path->entry_label(), | 2713 slow_path->entry_label(), |
| 2714 Assembler::kFarJump, | 2714 Assembler::kFarJump, |
| 2715 out_reg); | 2715 out_reg); |
| 2716 __ Bind(slow_path->exit_label()); | 2716 __ Bind(slow_path->exit_label()); |
| 2717 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | 2717 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); |
| 2718 } | 2718 } |
| 2719 | 2719 |
| 2720 | 2720 |
| 2721 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | 2721 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { |
| 2722 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2722 const intptr_t kNumInputs = 1; | 2723 const intptr_t kNumInputs = 1; |
| 2723 const intptr_t kNumTemps = 0; | 2724 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
| 2724 LocationSummary* summary = | 2725 LocationSummary* summary = |
| 2725 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2726 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2726 summary->set_in(0, Location::RequiresRegister()); | 2727 summary->set_in(0, Location::RequiresRegister()); |
| 2728 if (kNumTemps > 0) { |
| 2729 ASSERT(kNumTemps == 1); |
| 2730 summary->set_temp(0, Location::RequiresRegister()); |
| 2731 } |
| 2727 summary->set_out(Location::RequiresFpuRegister()); | 2732 summary->set_out(Location::RequiresFpuRegister()); |
| 2728 return summary; | 2733 return summary; |
| 2729 } | 2734 } |
| 2730 | 2735 |
| 2731 | 2736 |
| 2732 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2737 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2733 const intptr_t value_cid = value()->Type()->ToCid(); | 2738 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2734 const Register value = locs()->in(0).reg(); | 2739 const Register value = locs()->in(0).reg(); |
| 2735 const XmmRegister result = locs()->out().fpu_reg(); | 2740 const XmmRegister result = locs()->out().fpu_reg(); |
| 2736 | 2741 |
| 2737 ASSERT(value_cid == kFloat32x4Cid); | 2742 if (value_cid != kFloat32x4Cid) { |
| 2743 const Register temp = locs()->temp(0).reg(); |
| 2744 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2745 __ testl(value, Immediate(kSmiTagMask)); |
| 2746 __ j(ZERO, deopt); |
| 2747 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 2748 __ j(NOT_EQUAL, deopt); |
| 2749 } |
| 2738 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 2750 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
| 2739 } | 2751 } |
| 2740 | 2752 |
| 2741 | 2753 |
| 2754 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { |
| 2755 const intptr_t kNumInputs = 1; |
| 2756 const intptr_t kNumTemps = 0; |
| 2757 LocationSummary* summary = |
| 2758 new LocationSummary(kNumInputs, |
| 2759 kNumTemps, |
| 2760 LocationSummary::kCallOnSlowPath); |
| 2761 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2762 summary->set_out(Location::RequiresRegister()); |
| 2763 return summary; |
| 2764 } |
| 2765 |
| 2766 |
| 2767 class BoxUint32x4SlowPath : public SlowPathCode { |
| 2768 public: |
| 2769 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) |
| 2770 : instruction_(instruction) { } |
| 2771 |
| 2772 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2773 __ Comment("BoxUint32x4SlowPath"); |
| 2774 __ Bind(entry_label()); |
| 2775 const Class& uint32x4_class = compiler->uint32x4_class(); |
| 2776 const Code& stub = |
| 2777 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); |
| 2778 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); |
| 2779 |
| 2780 LocationSummary* locs = instruction_->locs(); |
| 2781 locs->live_registers()->Remove(locs->out()); |
| 2782 |
| 2783 compiler->SaveLiveRegisters(locs); |
| 2784 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 2785 &label, |
| 2786 PcDescriptors::kOther, |
| 2787 locs); |
| 2788 __ MoveRegister(locs->out().reg(), EAX); |
| 2789 compiler->RestoreLiveRegisters(locs); |
| 2790 |
| 2791 __ jmp(exit_label()); |
| 2792 } |
| 2793 |
| 2794 private: |
| 2795 BoxUint32x4Instr* instruction_; |
| 2796 }; |
| 2797 |
| 2798 |
| 2799 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2800 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); |
| 2801 compiler->AddSlowPathCode(slow_path); |
| 2802 |
| 2803 Register out_reg = locs()->out().reg(); |
| 2804 XmmRegister value = locs()->in(0).fpu_reg(); |
| 2805 |
| 2806 __ TryAllocate(compiler->uint32x4_class(), |
| 2807 slow_path->entry_label(), |
| 2808 Assembler::kFarJump, |
| 2809 out_reg); |
| 2810 __ Bind(slow_path->exit_label()); |
| 2811 __ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value); |
| 2812 } |
| 2813 |
| 2814 |
| 2815 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { |
| 2816 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2817 const intptr_t kNumInputs = 1; |
| 2818 const intptr_t kNumTemps = value_cid == kUint32x4Cid ? 0 : 1; |
| 2819 LocationSummary* summary = |
| 2820 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2821 summary->set_in(0, Location::RequiresRegister()); |
| 2822 if (kNumTemps > 0) { |
| 2823 ASSERT(kNumTemps == 1); |
| 2824 summary->set_temp(0, Location::RequiresRegister()); |
| 2825 } |
| 2826 summary->set_out(Location::RequiresFpuRegister()); |
| 2827 return summary; |
| 2828 } |
| 2829 |
| 2830 |
| 2831 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2832 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2833 const Register value = locs()->in(0).reg(); |
| 2834 const XmmRegister result = locs()->out().fpu_reg(); |
| 2835 |
| 2836 if (value_cid != kUint32x4Cid) { |
| 2837 const Register temp = locs()->temp(0).reg(); |
| 2838 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2839 __ testl(value, Immediate(kSmiTagMask)); |
| 2840 __ j(ZERO, deopt); |
| 2841 __ CompareClassId(value, kUint32x4Cid, temp); |
| 2842 __ j(NOT_EQUAL, deopt); |
| 2843 } |
| 2844 __ movups(result, FieldAddress(value, Uint32x4::value_offset())); |
| 2845 } |
| 2846 |
| 2847 |
| 2848 |
| 2742 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2849 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2743 const intptr_t kNumInputs = 2; | 2850 const intptr_t kNumInputs = 2; |
| 2744 const intptr_t kNumTemps = 0; | 2851 const intptr_t kNumTemps = 0; |
| 2745 LocationSummary* summary = | 2852 LocationSummary* summary = |
| 2746 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2853 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2747 summary->set_in(0, Location::RequiresFpuRegister()); | 2854 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2748 summary->set_in(1, Location::RequiresFpuRegister()); | 2855 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2749 summary->set_out(Location::SameAsFirstInput()); | 2856 summary->set_out(Location::SameAsFirstInput()); |
| 2750 return summary; | 2857 return summary; |
| 2751 } | 2858 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2913 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3020 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2914 XmmRegister value = locs()->out().fpu_reg(); | 3021 XmmRegister value = locs()->out().fpu_reg(); |
| 2915 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg()); | 3022 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg()); |
| 2916 // Convert to Float32. | 3023 // Convert to Float32. |
| 2917 __ cvtsd2ss(value, value); | 3024 __ cvtsd2ss(value, value); |
| 2918 // Splat across all lanes. | 3025 // Splat across all lanes. |
| 2919 __ shufps(value, value, Immediate(0x00)); | 3026 __ shufps(value, value, Immediate(0x00)); |
| 2920 } | 3027 } |
| 2921 | 3028 |
| 2922 | 3029 |
| 3030 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { |
| 3031 const intptr_t kNumInputs = 2; |
| 3032 const intptr_t kNumTemps = 0; |
| 3033 LocationSummary* summary = |
| 3034 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3035 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3036 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3037 summary->set_out(Location::SameAsFirstInput()); |
| 3038 return summary; |
| 3039 } |
| 3040 |
| 3041 |
| 3042 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3043 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3044 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3045 |
| 3046 ASSERT(locs()->out().fpu_reg() == left); |
| 3047 |
| 3048 switch (op_kind()) { |
| 3049 case MethodRecognizer::kFloat32x4Equal: |
| 3050 __ cmppseq(left, right); |
| 3051 break; |
| 3052 case MethodRecognizer::kFloat32x4NotEqual: |
| 3053 __ cmppsneq(left, right); |
| 3054 break; |
| 3055 case MethodRecognizer::kFloat32x4GreaterThan: |
| 3056 __ cmppsnle(left, right); |
| 3057 break; |
| 3058 case MethodRecognizer::kFloat32x4GreaterThanOrEqual: |
| 3059 __ cmppsnlt(left, right); |
| 3060 break; |
| 3061 case MethodRecognizer::kFloat32x4LessThan: |
| 3062 __ cmppslt(left, right); |
| 3063 break; |
| 3064 case MethodRecognizer::kFloat32x4LessThanOrEqual: |
| 3065 __ cmppsle(left, right); |
| 3066 break; |
| 3067 |
| 3068 default: UNREACHABLE(); |
| 3069 } |
| 3070 } |
| 3071 |
| 3072 |
| 2923 LocationSummary* MathSqrtInstr::MakeLocationSummary() const { | 3073 LocationSummary* MathSqrtInstr::MakeLocationSummary() const { |
| 2924 const intptr_t kNumInputs = 1; | 3074 const intptr_t kNumInputs = 1; |
| 2925 const intptr_t kNumTemps = 0; | 3075 const intptr_t kNumTemps = 0; |
| 2926 LocationSummary* summary = | 3076 LocationSummary* summary = |
| 2927 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3077 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2928 summary->set_in(0, Location::RequiresFpuRegister()); | 3078 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2929 summary->set_out(Location::RequiresFpuRegister()); | 3079 summary->set_out(Location::RequiresFpuRegister()); |
| 2930 return summary; | 3080 return summary; |
| 2931 } | 3081 } |
| 2932 | 3082 |
| (...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4030 PcDescriptors::kOther, | 4180 PcDescriptors::kOther, |
| 4031 locs()); | 4181 locs()); |
| 4032 __ Drop(2); // Discard type arguments and receiver. | 4182 __ Drop(2); // Discard type arguments and receiver. |
| 4033 } | 4183 } |
| 4034 | 4184 |
| 4035 } // namespace dart | 4185 } // namespace dart |
| 4036 | 4186 |
| 4037 #undef __ | 4187 #undef __ |
| 4038 | 4188 |
| 4039 #endif // defined TARGET_ARCH_IA32 | 4189 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |