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: runtime/vm/intermediate_language_ia32.cc

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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 (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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 5595 matching lines...) Expand 10 before | Expand all | Expand 10 after
5606 } 5606 }
5607 5607
5608 5608
5609 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, 5609 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5610 bool opt) const { 5610 bool opt) const {
5611 const intptr_t kNumInputs = 1; 5611 const intptr_t kNumInputs = 1;
5612 const intptr_t kNumTemps = 0; 5612 const intptr_t kNumTemps = 0;
5613 LocationSummary* summary = new(isolate) LocationSummary( 5613 LocationSummary* summary = new(isolate) LocationSummary(
5614 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5614 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5615 summary->set_in(0, Location::RequiresRegister()); 5615 summary->set_in(0, Location::RequiresRegister());
5616 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), 5616 if (is_32_bit()) {
5617 Location::RegisterLocation(EDX))); 5617 summary->set_out(0, Location::RequiresRegister());
5618 } else {
5619 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
5620 Location::RegisterLocation(EDX)));
5621 }
5618 return summary; 5622 return summary;
5619 } 5623 }
5620 5624
5621 5625
5622 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5626 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5623 const intptr_t value_cid = value()->Type()->ToCid(); 5627 const intptr_t value_cid = value()->Type()->ToCid();
5624 const Register value = locs()->in(0).reg(); 5628 const Register value = locs()->in(0).reg();
5629
5630 if (is_32_bit()) {
5631 const Register out = locs()->out(0).reg();
5632 if (value_cid == kMintCid) {
5633 __ movl(out, FieldAddress(value, Mint::value_offset()));
5634 } else if (value_cid == kSmiCid) {
5635 __ movl(out, value);
5636 __ SmiUntag(out);
5637 } else {
5638 Label* deopt = compiler->AddDeoptStub(deopt_id_,
5639 ICData::kDeoptUnboxInteger);
5640 Label is_smi, done;
5641 __ testl(value, Immediate(kSmiTagMask));
5642 __ j(ZERO, &is_smi);
5643 __ CompareClassId(value, kMintCid, out);
5644 __ j(NOT_EQUAL, deopt);
5645 __ movl(out, FieldAddress(value, Mint::value_offset()));
5646 __ jmp(&done);
5647 __ Bind(&is_smi);
5648 __ movl(out, value);
5649 __ SmiUntag(out);
5650 __ Bind(&done);
5651 }
5652 return;
5653 }
5654
5655 ASSERT(!is_32_bit());
5625 PairLocation* result_pair = locs()->out(0).AsPairLocation(); 5656 PairLocation* result_pair = locs()->out(0).AsPairLocation();
5626 Register result_lo = result_pair->At(0).reg(); 5657 Register result_lo = result_pair->At(0).reg();
5627 Register result_hi = result_pair->At(1).reg(); 5658 Register result_hi = result_pair->At(1).reg();
5628 5659
5629 ASSERT(value != result_lo); 5660 ASSERT(value != result_lo);
5630 ASSERT(value != result_hi); 5661 ASSERT(value != result_hi);
5631 ASSERT(result_lo == EAX); 5662 ASSERT(result_lo == EAX);
5632 ASSERT(result_hi == EDX); 5663 ASSERT(result_hi == EDX);
5633 5664
5634 if (value_cid == kMintCid) { 5665 if (value_cid == kMintCid) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
5760 kNoRegister); 5791 kNoRegister);
5761 __ Bind(slow_path->exit_label()); 5792 __ Bind(slow_path->exit_label());
5762 // 3. Restore lower half of input before using it. 5793 // 3. Restore lower half of input before using it.
5763 __ subl(value_lo, Immediate(0x40000000)); 5794 __ subl(value_lo, Immediate(0x40000000));
5764 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); 5795 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo);
5765 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); 5796 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi);
5766 __ Bind(&done); 5797 __ Bind(&done);
5767 } 5798 }
5768 5799
5769 5800
5801 LocationSummary* MintConverterInstr::MakeLocationSummary(Isolate* isolate,
5802 bool opt) const {
5803 // We should only see this in optimized code.
5804 ASSERT(opt);
5805 const intptr_t kNumInputs = 1;
5806 const intptr_t kNumTemps = 0;
5807 LocationSummary* summary = new(isolate) LocationSummary(
5808 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5809 if (conversion_kind() == kMint32ToMint) {
5810 summary->set_in(0, Location::RequiresRegister());
5811 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5812 Location::RequiresRegister()));
5813 } else if (conversion_kind() == kMintToMint32) {
5814 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5815 Location::RequiresRegister()));
5816 summary->set_out(0, Location::RequiresRegister());
5817 } else {
5818 UNREACHABLE();
5819 }
5820 return summary;
5821 }
5822
5823
5824 void MintConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5825 if (conversion_kind() == kMint32ToMint) {
5826 Register in = locs()->in(0).reg();
5827 PairLocation* out_pair = locs()->out(0).AsPairLocation();
5828 Register out_lo = out_pair->At(0).reg();
5829 Register out_hi = out_pair->At(1).reg();
5830 // Copy lo.
5831 __ movl(out_lo, in);
5832 // Zero hi.
5833 __ xorl(out_hi, out_hi);
5834 } else if (conversion_kind() == kMintToMint32) {
5835 PairLocation* in_pair = locs()->in(0).AsPairLocation();
5836 Register in_lo = in_pair->At(0).reg();
5837 Register out = locs()->out(0).reg();
5838 // Copy lo.
5839 __ movl(out, in_lo);
5840 } else {
5841 UNREACHABLE();
5842 }
5843 }
5844
5845
5846 static bool BinaryMintOutputSameAsInput(const BinaryMintOpInstr* instr) {
5847 return instr->is_32_bit() == instr->IsInput32Bit(0);
5848 }
5849
5770 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5850 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5771 bool opt) const { 5851 bool opt) const {
5772 const intptr_t kNumInputs = 2; 5852 const intptr_t kNumInputs = 2;
5853 // Need a temporary right high word if we are computing a 64-bit value
5854 // and the right operand is 32-bits.
5855 const intptr_t kNumTemps = (!is_32_bit() && IsInput32Bit(1)) ? 1 : 0;
5773 switch (op_kind()) { 5856 switch (op_kind()) {
5774 case Token::kBIT_AND: 5857 case Token::kBIT_AND:
5775 case Token::kBIT_OR: 5858 case Token::kBIT_OR:
5776 case Token::kBIT_XOR: { 5859 case Token::kBIT_XOR: {
5777 const intptr_t kNumTemps = 0;
5778 LocationSummary* summary = new(isolate) LocationSummary( 5860 LocationSummary* summary = new(isolate) LocationSummary(
5779 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5861 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5780 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5862
5781 Location::RequiresRegister())); 5863 if (kNumTemps > 0) {
5782 summary->set_in(1, Location::Pair(Location::RequiresRegister(), 5864 ASSERT(kNumTemps == 1);
5783 Location::RequiresRegister())); 5865 summary->set_temp(0, Location::RequiresRegister());
5784 summary->set_out(0, Location::SameAsFirstInput()); 5866 }
5867
5868 if (IsInput32Bit(0)) {
5869 summary->set_in(0, Location::RequiresRegister());
5870 } else {
5871 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5872 Location::RequiresRegister()));
5873 }
5874
5875 if (IsInput32Bit(1)) {
5876 summary->set_in(1, Location::RequiresRegister());
5877 } else {
5878 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5879 Location::RequiresRegister()));
5880 }
5881
5882 if (BinaryMintOutputSameAsInput(this)) {
5883 summary->set_out(0, Location::SameAsFirstInput());
5884 } else if (is_32_bit()) {
5885 summary->set_out(0, Location::RequiresRegister());
5886 } else {
5887 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5888 Location::RequiresRegister()));
5889 }
5785 return summary; 5890 return summary;
5786 } 5891 }
5787 case Token::kADD: 5892 case Token::kADD:
5788 case Token::kSUB: { 5893 case Token::kSUB: {
5789 const intptr_t kNumTemps = 0;
5790 LocationSummary* summary = new(isolate) LocationSummary( 5894 LocationSummary* summary = new(isolate) LocationSummary(
5791 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5895 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5792 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5896
5793 Location::RequiresRegister())); 5897 if (kNumTemps > 0) {
5794 summary->set_in(1, Location::Pair(Location::RequiresRegister(), 5898 ASSERT(kNumTemps == 1);
5795 Location::RequiresRegister())); 5899 summary->set_temp(0, Location::RequiresRegister());
5796 summary->set_out(0, Location::SameAsFirstInput()); 5900 }
5901 if (IsInput32Bit(0)) {
5902 summary->set_in(0, Location::RequiresRegister());
5903 } else {
5904 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5905 Location::RequiresRegister()));
5906 }
5907
5908 if (IsInput32Bit(1)) {
5909 summary->set_in(1, Location::RequiresRegister());
5910 } else {
5911 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5912 Location::RequiresRegister()));
5913 }
5914
5915 if (BinaryMintOutputSameAsInput(this)) {
5916 summary->set_out(0, Location::SameAsFirstInput());
5917 } else if (is_32_bit()) {
5918 summary->set_out(0, Location::RequiresRegister());
5919 } else {
5920 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5921 Location::RequiresRegister()));
5922 }
5797 return summary; 5923 return summary;
5798 } 5924 }
5799 default: 5925 default:
5800 UNREACHABLE(); 5926 UNREACHABLE();
5801 return NULL; 5927 return NULL;
5802 } 5928 }
5803 } 5929 }
5804 5930
5805 5931
5806 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5932 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5807 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 5933 Register left_lo = kNoRegister;
5808 Register left_lo = left_pair->At(0).reg(); 5934 Register left_hi = kNoRegister;
5809 Register left_hi = left_pair->At(1).reg(); 5935 Register right_lo = kNoRegister;
5810 PairLocation* right_pair = locs()->in(1).AsPairLocation(); 5936 Register right_hi = kNoRegister;
5811 Register right_lo = right_pair->At(0).reg(); 5937 Register out_lo = kNoRegister;
5812 Register right_hi = right_pair->At(1).reg(); 5938 Register out_hi = kNoRegister;
5939
5940 if (IsInput32Bit(0)) {
5941 left_lo = locs()->in(0).reg();
5942 } else {
5943 PairLocation* left_pair = locs()->in(0).AsPairLocation();
5944 left_lo = left_pair->At(0).reg();
5945 left_hi = left_pair->At(1).reg();
5946 }
5947
5948 if (IsInput32Bit(1)) {
5949 right_lo = locs()->in(1).reg();
5950 } else {
5951 PairLocation* right_pair = locs()->in(1).AsPairLocation();
5952 right_lo = right_pair->At(0).reg();
5953 right_hi = right_pair->At(1).reg();
5954 }
5955
5956 if (is_32_bit()) {
5957 out_lo = locs()->out(0).reg();
5958 if (!BinaryMintOutputSameAsInput(this)) {
5959 // Copy lo part of left.
5960 __ movl(out_lo, left_lo);
5961 } else {
5962 ASSERT(out_lo == left_lo);
5963 }
5964 switch (op_kind()) {
5965 case Token::kBIT_AND:
5966 __ andl(out_lo, right_lo);
5967 break;
5968 case Token::kBIT_OR:
5969 __ orl(out_lo, right_lo);
5970 break;
5971 case Token::kBIT_XOR:
5972 __ xorl(out_lo, right_lo);
5973 break;
5974 case Token::kADD:
5975 case Token::kSUB: {
5976 if (op_kind() == Token::kADD) {
5977 __ addl(out_lo, right_lo);
5978 } else {
5979 __ subl(out_lo, right_lo);
5980 }
5981 break;
5982 }
5983 default: UNREACHABLE();
5984 }
5985 return;
5986 }
5987
5988 ASSERT(!is_32_bit());
5989
5813 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 5990 PairLocation* out_pair = locs()->out(0).AsPairLocation();
5814 Register out_lo = out_pair->At(0).reg(); 5991 out_lo = out_pair->At(0).reg();
5815 Register out_hi = out_pair->At(1).reg(); 5992 out_hi = out_pair->At(1).reg();
5816 ASSERT(out_lo == left_lo); 5993 if (BinaryMintOutputSameAsInput(this)) {
5817 ASSERT(out_hi == left_hi); 5994 ASSERT(out_lo == left_lo);
5995 ASSERT(out_hi == left_hi);
5996 } else {
5997 // Left input is 32-bits.
5998 ASSERT(IsInput32Bit(0));
5999 // Copy lo input.
6000 __ movl(out_lo, left_lo);
6001 // Zero output.
6002 __ xorl(out_hi, out_hi);
6003 }
6004
6005 if (IsInput32Bit(1)) {
6006 // Zero temporary right high word.
6007 right_hi = locs()->temp(0).reg();
6008 __ xorl(right_hi, right_hi);
6009 }
5818 6010
5819 Label* deopt = NULL; 6011 Label* deopt = NULL;
5820 if (FLAG_throw_on_javascript_int_overflow) { 6012 if (FLAG_throw_on_javascript_int_overflow) {
5821 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); 6013 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5822 } 6014 }
5823 switch (op_kind()) { 6015 switch (op_kind()) {
5824 case Token::kBIT_AND: 6016 case Token::kBIT_AND:
5825 __ andl(left_lo, right_lo); 6017 __ andl(out_lo, right_lo);
5826 __ andl(left_hi, right_hi); 6018 __ andl(out_hi, right_hi);
5827 break; 6019 break;
5828 case Token::kBIT_OR: 6020 case Token::kBIT_OR:
5829 __ orl(left_lo, right_lo); 6021 __ orl(out_lo, right_lo);
5830 __ orl(left_hi, right_hi); 6022 __ orl(out_hi, right_hi);
5831 break; 6023 break;
5832 case Token::kBIT_XOR: 6024 case Token::kBIT_XOR:
5833 __ xorl(left_lo, right_lo); 6025 __ xorl(out_lo, right_lo);
5834 __ xorl(left_hi, right_hi); 6026 __ xorl(out_hi, right_hi);
5835 break; 6027 break;
5836 case Token::kADD: 6028 case Token::kADD:
5837 case Token::kSUB: { 6029 case Token::kSUB: {
5838 if (!FLAG_throw_on_javascript_int_overflow) { 6030 if (!FLAG_throw_on_javascript_int_overflow) {
5839 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); 6031 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
5840 } 6032 }
5841 if (op_kind() == Token::kADD) { 6033 if (op_kind() == Token::kADD) {
5842 __ addl(left_lo, right_lo); 6034 __ addl(out_lo, right_lo);
5843 __ adcl(left_hi, right_hi); 6035 __ adcl(out_hi, right_hi);
5844 } else { 6036 } else {
5845 __ subl(left_lo, right_lo); 6037 __ subl(out_lo, right_lo);
5846 __ sbbl(left_hi, right_hi); 6038 __ sbbl(out_hi, right_hi);
5847 } 6039 }
5848 __ j(OVERFLOW, deopt); 6040 __ j(OVERFLOW, deopt);
5849 break; 6041 break;
5850 } 6042 }
5851 default: UNREACHABLE(); 6043 default: UNREACHABLE();
5852 } 6044 }
5853 if (FLAG_throw_on_javascript_int_overflow) { 6045 if (FLAG_throw_on_javascript_int_overflow) {
5854 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6046 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
5855 } 6047 }
5856 } 6048 }
5857 6049
5858 6050
6051 static bool ShiftMintOpInstrOutputSameAsInput(const ShiftMintOpInstr* instr) {
6052 return instr->is_32_bit() == instr->IsInput32Bit(0);
6053 }
6054
6055
5859 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 6056 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5860 bool opt) const { 6057 bool opt) const {
6058 const bool need_temps = (op_kind() == Token::kSHL) && CanShiftLeftOverflow();
5861 const intptr_t kNumInputs = 2; 6059 const intptr_t kNumInputs = 2;
5862 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 0; 6060 const intptr_t kNumTemps = need_temps ? 2 : 0;
5863 LocationSummary* summary = new(isolate) LocationSummary( 6061 LocationSummary* summary = new(isolate) LocationSummary(
5864 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6062 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5865 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 6063
5866 Location::RequiresRegister())); 6064
6065 if (IsInput32Bit(0)) {
6066 summary->set_in(0, Location::RequiresRegister());
6067 } else {
6068 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6069 Location::RequiresRegister()));
6070 }
6071
5867 summary->set_in(1, Location::RegisterLocation(ECX)); 6072 summary->set_in(1, Location::RegisterLocation(ECX));
5868 if (op_kind() == Token::kSHL) { 6073
6074 if (need_temps) {
5869 summary->set_temp(0, Location::RequiresRegister()); 6075 summary->set_temp(0, Location::RequiresRegister());
5870 summary->set_temp(1, Location::RequiresRegister()); 6076 summary->set_temp(1, Location::RequiresRegister());
5871 } 6077 }
5872 summary->set_out(0, Location::SameAsFirstInput()); 6078
6079 if (ShiftMintOpInstrOutputSameAsInput(this)) {
6080 summary->set_out(0, Location::SameAsFirstInput());
6081 } else if (is_32_bit()) {
6082 summary->set_out(0, Location::RequiresRegister());
6083 } else {
6084 ASSERT(IsInput32Bit(0));
6085 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6086 Location::RequiresRegister()));
6087 }
6088
5873 return summary; 6089 return summary;
5874 } 6090 }
5875 6091
5876 6092
5877 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6093 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5878 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 6094 // Shift count is in ECX.
5879 Register left_lo = left_pair->At(0).reg(); 6095 ASSERT(locs()->in(1).reg() == ECX);
5880 Register left_hi = left_pair->At(1).reg(); 6096 Register left_lo;
5881 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 6097 Register left_hi;
5882 Register out_lo = out_pair->At(0).reg(); 6098 Register out_lo;
5883 Register out_hi = out_pair->At(1).reg(); 6099 Register out_hi;
5884 ASSERT(out_lo == left_lo);
5885 ASSERT(out_hi == left_hi);
5886 6100
5887 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); 6101 if (IsInput32Bit(0)) {
6102 left_lo = locs()->in(0).reg();
6103 left_hi = kNoRegister;
6104 } else {
6105 PairLocation* left_pair = locs()->in(0).AsPairLocation();
6106 left_lo = left_pair->At(0).reg();
6107 left_hi = left_pair->At(1).reg();
6108 }
6109
6110 if (is_32_bit()) {
6111 out_lo = locs()->out(0).reg();
6112 out_hi = kNoRegister;
6113 } else {
6114 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6115 out_lo = out_pair->At(0).reg();
6116 out_hi = out_pair->At(1).reg();
6117 }
6118
6119 if (ShiftMintOpInstrOutputSameAsInput(this)) {
6120 ASSERT(out_lo == left_lo);
6121 ASSERT(out_hi == left_hi);
6122 } else if (is_32_bit()) {
6123 ASSERT(!IsInput32Bit(0));
6124 // Copy lo.
6125 __ movl(out_lo, left_lo);
6126 } else if (IsInput32Bit(0)) {
6127 ASSERT(!is_32_bit());
6128 // Copy lo.
6129 __ movl(out_lo, left_lo);
6130 // Zero hi.
6131 __ xorl(out_hi, out_hi);
6132 }
6133
6134
5888 Label done; 6135 Label done;
5889 __ testl(ECX, ECX); 6136 __ testl(ECX, ECX);
5890 __ j(ZERO, &done); // Shift by 0 is a nop. 6137 __ j(ZERO, &done); // Shift by 0 is a nop.
6138 __ SmiUntag(ECX);
6139
5891 // Deoptimize if shift count is > 31. 6140 // Deoptimize if shift count is > 31.
5892 // sarl operation masks the count to 5 bits and 6141 // sarl operation masks the count to 5 bits and
5893 // shrd is undefined with count > operand size (32) 6142 // shrd is undefined with count > operand size (32)
5894 // TODO(fschneider): Support shift counts > 31 without deoptimization. 6143 // TODO(fschneider): Support shift counts > 31 without deoptimization.
5895 __ SmiUntag(ECX); 6144
6145 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
5896 const Immediate& kCountLimit = Immediate(31); 6146 const Immediate& kCountLimit = Immediate(31);
5897 __ cmpl(ECX, kCountLimit); 6147 __ cmpl(ECX, kCountLimit);
5898 __ j(ABOVE, deopt); 6148 __ j(ABOVE, deopt);
6149
5899 switch (op_kind()) { 6150 switch (op_kind()) {
5900 case Token::kSHR: { 6151 case Token::kSHR: {
5901 __ shrd(left_lo, left_hi); // Shift count in CL. 6152 if (IsInput32Bit(0)) {
5902 __ sarl(left_hi, ECX); // Shift count in CL. 6153 // 32-bit input.
6154 // Upper word is 0, use logical shift.
6155 __ shrl(out_lo, ECX);
6156 // If needed, out_hi is already zero.
6157 } else {
6158 // 64-bit input,
6159 if (is_32_bit()) {
6160 // 32-bit output
6161 __ shrd(out_lo, left_hi); // Shift count in CL.
6162 } else {
6163 // 64-bit output.
6164 __ shrd(out_lo, left_hi); // Shift count in CL.
6165 __ sarl(out_hi, ECX); // Shift count in CL.
6166 }
6167 }
5903 break; 6168 break;
5904 } 6169 }
5905 case Token::kSHL: { 6170 case Token::kSHL: {
5906 Register temp1 = locs()->temp(0).reg(); 6171 if (CanShiftLeftOverflow()) {
5907 Register temp2 = locs()->temp(1).reg(); 6172 // 64-bit input and 64-bit output.
5908 __ movl(temp1, left_lo); // Low 32 bits. 6173 Register temp1 = locs()->temp(0).reg();
5909 __ movl(temp2, left_hi); // High 32 bits. 6174 Register temp2 = locs()->temp(1).reg();
5910 __ shll(left_lo, ECX); // Shift count in CL. 6175 __ movl(temp1, out_lo); // Low 32 bits.
5911 __ shld(left_hi, temp1); // Shift count in CL. 6176 __ movl(temp2, out_hi); // High 32 bits.
5912 // Check for overflow by shifting back the high 32 bits 6177 __ shll(out_lo, ECX); // Shift count in CL.
5913 // and comparing with the input. 6178 __ shld(out_hi, temp1); // Shift count in CL.
5914 __ movl(temp1, temp2); 6179 // Check for overflow by shifting back the high 32 bits
5915 __ movl(temp2, left_hi); 6180 // and comparing with the input.
5916 __ sarl(temp2, ECX); 6181 __ movl(temp1, temp2);
5917 __ cmpl(temp1, temp2); 6182 __ movl(temp2, out_hi);
5918 __ j(NOT_EQUAL, deopt); 6183 __ sarl(temp2, ECX);
6184 __ cmpl(temp1, temp2);
6185 __ j(NOT_EQUAL, deopt);
6186 } else {
6187 if (is_32_bit()) {
6188 // 32-bit output (can be 64-bit or 32-bit input).
6189 __ shll(out_lo, ECX);
6190 } else {
6191 // 64-bit output and 32-bit input.
6192 ASSERT(out_lo != left_lo);
6193 __ shll(out_lo, ECX);
6194 __ shld(out_hi, left_lo);
6195 }
6196 }
5919 break; 6197 break;
5920 } 6198 }
5921 default: 6199 default:
5922 UNREACHABLE(); 6200 UNREACHABLE();
5923 break; 6201 break;
5924 } 6202 }
5925 __ Bind(&done); 6203 __ Bind(&done);
5926 if (FLAG_throw_on_javascript_int_overflow) { 6204 if (FLAG_throw_on_javascript_int_overflow && !is_32_bit()) {
5927 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6205 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
5928 } 6206 }
5929 } 6207 }
5930 6208
5931 6209
6210 static bool UnaryMintOutputSameAsInput(const UnaryMintOpInstr* instr) {
6211 return instr->is_32_bit() == instr->IsInput32Bit(0);
6212 }
6213
6214
5932 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 6215 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5933 bool opt) const { 6216 bool opt) const {
5934 const intptr_t kNumInputs = 1; 6217 const intptr_t kNumInputs = 1;
5935 const intptr_t kNumTemps = 0; 6218 const intptr_t kNumTemps = 0;
5936 LocationSummary* summary = new(isolate) LocationSummary( 6219 LocationSummary* summary = new(isolate) LocationSummary(
5937 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6220 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5938 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 6221
5939 Location::RequiresRegister())); 6222 if (IsInput32Bit(0)) {
5940 summary->set_out(0, Location::SameAsFirstInput()); 6223 summary->set_in(0, Location::RequiresRegister());
5941 if (FLAG_throw_on_javascript_int_overflow) { 6224 } else {
5942 summary->set_temp(0, Location::RequiresRegister()); 6225 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6226 Location::RequiresRegister()));
6227 }
6228
6229 if (UnaryMintOutputSameAsInput(this)) {
6230 summary->set_out(0, Location::SameAsFirstInput());
6231 } else if (IsInput32Bit(0)) {
6232 ASSERT(!is_32_bit());
6233 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6234 Location::RequiresRegister()));
6235 } else {
6236 ASSERT(is_32_bit());
6237 summary->set_out(0, Location::RequiresRegister());
5943 } 6238 }
5944 return summary; 6239 return summary;
5945 } 6240 }
5946 6241
5947 6242
5948 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6243 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5949 ASSERT(op_kind() == Token::kBIT_NOT); 6244 ASSERT(op_kind() == Token::kBIT_NOT);
5950 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 6245
5951 Register left_lo = left_pair->At(0).reg(); 6246 // Extract registers.
5952 Register left_hi = left_pair->At(1).reg(); 6247 Register out_lo;
5953 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 6248 Register out_hi = kNoRegister;
5954 Register out_lo = out_pair->At(0).reg(); 6249 Register left_lo;
5955 Register out_hi = out_pair->At(1).reg(); 6250 Register left_hi = kNoRegister;
5956 ASSERT(out_lo == left_lo); 6251
5957 ASSERT(out_hi == left_hi); 6252 if (IsInput32Bit(0)) {
6253 left_lo = locs()->in(0).reg();
6254 } else {
6255 PairLocation* left_pair = locs()->in(0).AsPairLocation();
6256 left_lo = left_pair->At(0).reg();
6257 left_hi = left_pair->At(1).reg();
6258 }
6259
6260 if (is_32_bit()) {
6261 out_lo = locs()->out(0).reg();
6262 } else {
6263 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6264 out_lo = out_pair->At(0).reg();
6265 out_hi = out_pair->At(1).reg();
6266 }
6267
6268 if (UnaryMintOutputSameAsInput(this)) {
6269 ASSERT(out_lo == left_lo);
6270 ASSERT(out_hi == left_hi);
6271 } else {
6272 __ movl(out_lo, left_lo);
6273 if (!is_32_bit() && IsInput32Bit(0)) {
6274 // Zero high word.
6275 __ xorl(out_hi, out_hi);
6276 }
6277 }
5958 6278
5959 Label* deopt = NULL; 6279 Label* deopt = NULL;
5960 if (FLAG_throw_on_javascript_int_overflow) { 6280 if (FLAG_throw_on_javascript_int_overflow && !is_32_bit()) {
5961 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); 6281 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
5962 } 6282 }
5963 6283
5964 __ notl(left_lo); 6284 __ notl(out_lo);
5965 __ notl(left_hi); 6285 if (!is_32_bit()) {
6286 __ notl(out_hi);
6287 }
5966 6288
5967 if (FLAG_throw_on_javascript_int_overflow) { 6289 if (FLAG_throw_on_javascript_int_overflow && !is_32_bit()) {
5968 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6290 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
5969 } 6291 }
5970 } 6292 }
5971 6293
5972 6294
5973 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6295 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
5974 bool opt) const { 6296 bool opt) const {
5975 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6297 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
5976 } 6298 }
5977 6299
5978 6300
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
6320 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6642 __ movl(EDX, Immediate(kInvalidObjectPointer));
6321 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6643 __ movl(EDX, Immediate(kInvalidObjectPointer));
6322 #endif 6644 #endif
6323 } 6645 }
6324 6646
6325 } // namespace dart 6647 } // namespace dart
6326 6648
6327 #undef __ 6649 #undef __
6328 6650
6329 #endif // defined TARGET_ARCH_IA32 6651 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698