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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 5911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5922 } | 5922 } |
5923 switch (op_kind()) { | 5923 switch (op_kind()) { |
5924 case Token::kSHR: { | 5924 case Token::kSHR: { |
5925 if (shift > 31) { | 5925 if (shift > 31) { |
5926 __ movl(left_lo, left_hi); // Shift by 32. | 5926 __ movl(left_lo, left_hi); // Shift by 32. |
5927 __ sarl(left_hi, Immediate(31)); // Sign extend left hi. | 5927 __ sarl(left_hi, Immediate(31)); // Sign extend left hi. |
5928 if (shift > 32) { | 5928 if (shift > 32) { |
5929 __ sarl(left_lo, Immediate(shift - 32)); | 5929 __ sarl(left_lo, Immediate(shift - 32)); |
5930 } | 5930 } |
5931 } else { | 5931 } else { |
5932 __ shrd(left_lo, left_hi, Immediate(shift)); | 5932 __ shrdl(left_lo, left_hi, Immediate(shift)); |
5933 __ sarl(left_hi, Immediate(shift)); | 5933 __ sarl(left_hi, Immediate(shift)); |
5934 } | 5934 } |
5935 break; | 5935 break; |
5936 } | 5936 } |
5937 case Token::kSHL: { | 5937 case Token::kSHL: { |
5938 if (can_overflow()) { | 5938 if (can_overflow()) { |
5939 Register temp1 = locs()->temp(0).reg(); | 5939 Register temp1 = locs()->temp(0).reg(); |
5940 Register temp2 = locs()->temp(1).reg(); | 5940 Register temp2 = locs()->temp(1).reg(); |
5941 __ movl(temp1, left_hi); // Preserve high 32 bits. | 5941 __ movl(temp1, left_hi); // Preserve high 32 bits. |
5942 if (shift > 31) { | 5942 if (shift > 31) { |
5943 __ movl(left_hi, left_lo); // Shift by 32. | 5943 __ movl(left_hi, left_lo); // Shift by 32. |
5944 __ xorl(left_lo, left_lo); // Zero left_lo. | 5944 __ xorl(left_lo, left_lo); // Zero left_lo. |
5945 if (shift > 32) { | 5945 if (shift > 32) { |
5946 __ shll(left_hi, Immediate(shift - 32)); | 5946 __ shll(left_hi, Immediate(shift - 32)); |
5947 } | 5947 } |
5948 // Check for overflow by sign extending the high 32 bits | 5948 // Check for overflow by sign extending the high 32 bits |
5949 // and comparing with the input. | 5949 // and comparing with the input. |
5950 __ movl(temp2, left_hi); | 5950 __ movl(temp2, left_hi); |
5951 __ sarl(temp2, Immediate(31)); | 5951 __ sarl(temp2, Immediate(31)); |
5952 __ cmpl(temp1, temp2); | 5952 __ cmpl(temp1, temp2); |
5953 __ j(NOT_EQUAL, deopt); | 5953 __ j(NOT_EQUAL, deopt); |
5954 } else { | 5954 } else { |
5955 __ shld(left_hi, left_lo, Immediate(shift)); | 5955 __ shldl(left_hi, left_lo, Immediate(shift)); |
5956 __ shll(left_lo, Immediate(shift)); | 5956 __ shll(left_lo, Immediate(shift)); |
5957 // Check for overflow by shifting back the high 32 bits | 5957 // Check for overflow by shifting back the high 32 bits |
5958 // and comparing with the input. | 5958 // and comparing with the input. |
5959 __ movl(temp2, left_hi); | 5959 __ movl(temp2, left_hi); |
5960 __ sarl(temp2, Immediate(shift)); | 5960 __ sarl(temp2, Immediate(shift)); |
5961 __ cmpl(temp1, temp2); | 5961 __ cmpl(temp1, temp2); |
5962 __ j(NOT_EQUAL, deopt); | 5962 __ j(NOT_EQUAL, deopt); |
5963 } | 5963 } |
5964 } else { | 5964 } else { |
5965 if (shift > 31) { | 5965 if (shift > 31) { |
5966 __ movl(left_hi, left_lo); // Shift by 32. | 5966 __ movl(left_hi, left_lo); // Shift by 32. |
5967 __ xorl(left_lo, left_lo); // Zero left_lo. | 5967 __ xorl(left_lo, left_lo); // Zero left_lo. |
5968 if (shift > 32) { | 5968 if (shift > 32) { |
5969 __ shll(left_hi, Immediate(shift - 32)); | 5969 __ shll(left_hi, Immediate(shift - 32)); |
5970 } | 5970 } |
5971 } else { | 5971 } else { |
5972 __ shld(left_hi, left_lo, Immediate(shift)); | 5972 __ shldl(left_hi, left_lo, Immediate(shift)); |
5973 __ shll(left_lo, Immediate(shift)); | 5973 __ shll(left_lo, Immediate(shift)); |
5974 } | 5974 } |
5975 } | 5975 } |
5976 break; | 5976 break; |
5977 } | 5977 } |
5978 default: | 5978 default: |
5979 UNREACHABLE(); | 5979 UNREACHABLE(); |
5980 } | 5980 } |
5981 } else { | 5981 } else { |
5982 // Code for a variable shift amount. | 5982 // Code for a variable shift amount. |
5983 // Deoptimize if shift count is > 63. | 5983 // Deoptimize if shift count is > 63. |
5984 // sarl operation masks the count to 5 bits and | 5984 // sarl operation masks the count to 5 bits and |
5985 // shrd is undefined with count > operand size (32) | 5985 // shrdl is undefined with count > operand size (32) |
5986 __ SmiUntag(ECX); | 5986 __ SmiUntag(ECX); |
5987 if (has_shift_count_check()) { | 5987 if (has_shift_count_check()) { |
5988 __ cmpl(ECX, Immediate(kMintShiftCountLimit)); | 5988 __ cmpl(ECX, Immediate(kMintShiftCountLimit)); |
5989 __ j(ABOVE, deopt); | 5989 __ j(ABOVE, deopt); |
5990 } | 5990 } |
5991 Label done, large_shift; | 5991 Label done, large_shift; |
5992 switch (op_kind()) { | 5992 switch (op_kind()) { |
5993 case Token::kSHR: { | 5993 case Token::kSHR: { |
5994 __ cmpl(ECX, Immediate(31)); | 5994 __ cmpl(ECX, Immediate(31)); |
5995 __ j(ABOVE, &large_shift); | 5995 __ j(ABOVE, &large_shift); |
5996 | 5996 |
5997 __ shrd(left_lo, left_hi); // Shift count in CL. | 5997 __ shrdl(left_lo, left_hi); // Shift count in CL. |
5998 __ sarl(left_hi, ECX); // Shift count in CL. | 5998 __ sarl(left_hi, ECX); // Shift count in CL. |
5999 __ jmp(&done, Assembler::kNearJump); | 5999 __ jmp(&done, Assembler::kNearJump); |
6000 | 6000 |
6001 __ Bind(&large_shift); | 6001 __ Bind(&large_shift); |
6002 // No need to subtract 32 from CL, only 5 bits used by sarl. | 6002 // No need to subtract 32 from CL, only 5 bits used by sarl. |
6003 __ movl(left_lo, left_hi); // Shift by 32. | 6003 __ movl(left_lo, left_hi); // Shift by 32. |
6004 __ sarl(left_hi, Immediate(31)); // Sign extend left hi. | 6004 __ sarl(left_hi, Immediate(31)); // Sign extend left hi. |
6005 __ sarl(left_lo, ECX); // Shift count: CL % 32. | 6005 __ sarl(left_lo, ECX); // Shift count: CL % 32. |
6006 break; | 6006 break; |
6007 } | 6007 } |
6008 case Token::kSHL: { | 6008 case Token::kSHL: { |
6009 if (can_overflow()) { | 6009 if (can_overflow()) { |
6010 Register temp1 = locs()->temp(0).reg(); | 6010 Register temp1 = locs()->temp(0).reg(); |
6011 Register temp2 = locs()->temp(1).reg(); | 6011 Register temp2 = locs()->temp(1).reg(); |
6012 __ movl(temp1, left_hi); // Preserve high 32 bits. | 6012 __ movl(temp1, left_hi); // Preserve high 32 bits. |
6013 __ cmpl(ECX, Immediate(31)); | 6013 __ cmpl(ECX, Immediate(31)); |
6014 __ j(ABOVE, &large_shift); | 6014 __ j(ABOVE, &large_shift); |
6015 | 6015 |
6016 __ shld(left_hi, left_lo); // Shift count in CL. | 6016 __ shldl(left_hi, left_lo); // Shift count in CL. |
6017 __ shll(left_lo, ECX); // Shift count in CL. | 6017 __ shll(left_lo, ECX); // Shift count in CL. |
6018 // Check for overflow by shifting back the high 32 bits | 6018 // Check for overflow by shifting back the high 32 bits |
6019 // and comparing with the input. | 6019 // and comparing with the input. |
6020 __ movl(temp2, left_hi); | 6020 __ movl(temp2, left_hi); |
6021 __ sarl(temp2, ECX); | 6021 __ sarl(temp2, ECX); |
6022 __ cmpl(temp1, temp2); | 6022 __ cmpl(temp1, temp2); |
6023 __ j(NOT_EQUAL, deopt); | 6023 __ j(NOT_EQUAL, deopt); |
6024 __ jmp(&done, Assembler::kNearJump); | 6024 __ jmp(&done, Assembler::kNearJump); |
6025 | 6025 |
6026 __ Bind(&large_shift); | 6026 __ Bind(&large_shift); |
6027 // No need to subtract 32 from CL, only 5 bits used by shll. | 6027 // No need to subtract 32 from CL, only 5 bits used by shll. |
6028 __ movl(left_hi, left_lo); // Shift by 32. | 6028 __ movl(left_hi, left_lo); // Shift by 32. |
6029 __ xorl(left_lo, left_lo); // Zero left_lo. | 6029 __ xorl(left_lo, left_lo); // Zero left_lo. |
6030 __ shll(left_hi, ECX); // Shift count: CL % 32. | 6030 __ shll(left_hi, ECX); // Shift count: CL % 32. |
6031 // Check for overflow by sign extending the high 32 bits | 6031 // Check for overflow by sign extending the high 32 bits |
6032 // and comparing with the input. | 6032 // and comparing with the input. |
6033 __ movl(temp2, left_hi); | 6033 __ movl(temp2, left_hi); |
6034 __ sarl(temp2, Immediate(31)); | 6034 __ sarl(temp2, Immediate(31)); |
6035 __ cmpl(temp1, temp2); | 6035 __ cmpl(temp1, temp2); |
6036 __ j(NOT_EQUAL, deopt); | 6036 __ j(NOT_EQUAL, deopt); |
6037 } else { | 6037 } else { |
6038 __ cmpl(ECX, Immediate(31)); | 6038 __ cmpl(ECX, Immediate(31)); |
6039 __ j(ABOVE, &large_shift); | 6039 __ j(ABOVE, &large_shift); |
6040 | 6040 |
6041 __ shld(left_hi, left_lo); // Shift count in CL. | 6041 __ shldl(left_hi, left_lo); // Shift count in CL. |
6042 __ shll(left_lo, ECX); // Shift count in CL. | 6042 __ shll(left_lo, ECX); // Shift count in CL. |
6043 __ jmp(&done, Assembler::kNearJump); | 6043 __ jmp(&done, Assembler::kNearJump); |
6044 | 6044 |
6045 __ Bind(&large_shift); | 6045 __ Bind(&large_shift); |
6046 // No need to subtract 32 from CL, only 5 bits used by shll. | 6046 // No need to subtract 32 from CL, only 5 bits used by shll. |
6047 __ movl(left_hi, left_lo); // Shift by 32. | 6047 __ movl(left_hi, left_lo); // Shift by 32. |
6048 __ xorl(left_lo, left_lo); // Zero left_lo. | 6048 __ xorl(left_lo, left_lo); // Zero left_lo. |
6049 __ shll(left_hi, ECX); // Shift count: CL % 32. | 6049 __ shll(left_hi, ECX); // Shift count: CL % 32. |
6050 } | 6050 } |
6051 break; | 6051 break; |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6781 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6781 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6782 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6782 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6783 #endif | 6783 #endif |
6784 } | 6784 } |
6785 | 6785 |
6786 } // namespace dart | 6786 } // namespace dart |
6787 | 6787 |
6788 #undef __ | 6788 #undef __ |
6789 | 6789 |
6790 #endif // defined TARGET_ARCH_IA32 | 6790 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |