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

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

Powered by Google App Engine
This is Rietveld 408576698