| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 const Object& constant = index->definition()->AsConstant()->value(); | 923 const Object& constant = index->definition()->AsConstant()->value(); |
| 924 if (!constant.IsSmi()) return false; | 924 if (!constant.IsSmi()) return false; |
| 925 const Smi& smi_const = Smi::Cast(constant); | 925 const Smi& smi_const = Smi::Cast(constant); |
| 926 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); | 926 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
| 927 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); | 927 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
| 928 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; | 928 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
| 929 return Utils::IsInt(32, disp); | 929 return Utils::IsInt(32, disp); |
| 930 } | 930 } |
| 931 | 931 |
| 932 | 932 |
| 933 LocationSummary* StringCharCodeAtInstr::MakeLocationSummary() const { | |
| 934 const intptr_t kNumInputs = 2; | |
| 935 const intptr_t kNumTemps = 0; | |
| 936 LocationSummary* locs = | |
| 937 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 938 locs->set_in(0, Location::RequiresRegister()); | |
| 939 // The smi index is either untagged and tagged again at the end of the | |
| 940 // operation (element size == 1), or it is left smi tagged (for all element | |
| 941 // sizes > 1). | |
| 942 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | |
| 943 ? Location::RegisterOrSmiConstant(index()) | |
| 944 : Location::RequiresRegister()); | |
| 945 locs->set_out(Location::RequiresRegister()); | |
| 946 return locs; | |
| 947 } | |
| 948 | |
| 949 | |
| 950 void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 951 Register str = locs()->in(0).reg(); | |
| 952 Location index = locs()->in(1); | |
| 953 Register result = locs()->out().reg(); | |
| 954 | |
| 955 ASSERT((class_id() == kOneByteStringCid) || | |
| 956 (class_id() == kTwoByteStringCid)); | |
| 957 | |
| 958 FieldAddress element_address = index.IsRegister() ? | |
| 959 FlowGraphCompiler::ElementAddressForRegIndex( | |
| 960 class_id(), str, index.reg()) : | |
| 961 FlowGraphCompiler::ElementAddressForIntIndex( | |
| 962 class_id(), str, Smi::Cast(index.constant()).Value()); | |
| 963 | |
| 964 if (class_id() == kOneByteStringCid) { | |
| 965 if (index.IsRegister()) { | |
| 966 __ SmiUntag(index.reg()); | |
| 967 } | |
| 968 __ movzxb(result, element_address); | |
| 969 if (index.IsRegister()) { | |
| 970 __ SmiTag(index.reg()); // Retag index. | |
| 971 } | |
| 972 __ SmiTag(result); | |
| 973 } else { | |
| 974 // Don't untag smi-index and use TIMES_1 for two byte strings. | |
| 975 __ movzxw(result, element_address); | |
| 976 __ SmiTag(result); | |
| 977 } | |
| 978 } | |
| 979 | |
| 980 | |
| 981 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 933 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { |
| 982 const intptr_t kNumInputs = 1; | 934 const intptr_t kNumInputs = 1; |
| 983 const intptr_t kNumTemps = 0; | 935 const intptr_t kNumTemps = 0; |
| 984 LocationSummary* locs = | 936 LocationSummary* locs = |
| 985 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 937 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 986 // TODO(fschneider): Allow immediate operands for the char code. | 938 // TODO(fschneider): Allow immediate operands for the char code. |
| 987 locs->set_in(0, Location::RequiresRegister()); | 939 locs->set_in(0, Location::RequiresRegister()); |
| 988 locs->set_out(Location::RequiresRegister()); | 940 locs->set_out(Location::RequiresRegister()); |
| 989 return locs; | 941 return locs; |
| 990 } | 942 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 __ movsd(result, element_address); | 1019 __ movsd(result, element_address); |
| 1068 } | 1020 } |
| 1069 return; | 1021 return; |
| 1070 } | 1022 } |
| 1071 | 1023 |
| 1072 Register result = locs()->out().reg(); | 1024 Register result = locs()->out().reg(); |
| 1073 switch (class_id()) { | 1025 switch (class_id()) { |
| 1074 case kInt8ArrayCid: | 1026 case kInt8ArrayCid: |
| 1075 case kUint8ArrayCid: | 1027 case kUint8ArrayCid: |
| 1076 case kUint8ClampedArrayCid: | 1028 case kUint8ClampedArrayCid: |
| 1029 case kOneByteStringCid: |
| 1077 if (index.IsRegister()) { | 1030 if (index.IsRegister()) { |
| 1078 __ SmiUntag(index.reg()); | 1031 __ SmiUntag(index.reg()); |
| 1079 } | 1032 } |
| 1080 if (class_id() == kInt8ArrayCid) { | 1033 if (class_id() == kInt8ArrayCid) { |
| 1081 __ movsxb(result, element_address); | 1034 __ movsxb(result, element_address); |
| 1082 } else { | 1035 } else { |
| 1083 __ movzxb(result, element_address); | 1036 __ movzxb(result, element_address); |
| 1084 } | 1037 } |
| 1085 __ SmiTag(result); | 1038 __ SmiTag(result); |
| 1086 if (index.IsRegister()) { | 1039 if (index.IsRegister()) { |
| 1087 __ SmiTag(index.reg()); // Re-tag. | 1040 __ SmiTag(index.reg()); // Re-tag. |
| 1088 } | 1041 } |
| 1089 break; | 1042 break; |
| 1090 case kInt16ArrayCid: | 1043 case kInt16ArrayCid: |
| 1091 __ movsxw(result, element_address); | 1044 __ movsxw(result, element_address); |
| 1092 __ SmiTag(result); | 1045 __ SmiTag(result); |
| 1093 break; | 1046 break; |
| 1094 case kUint16ArrayCid: | 1047 case kUint16ArrayCid: |
| 1048 case kTwoByteStringCid: |
| 1095 __ movzxw(result, element_address); | 1049 __ movzxw(result, element_address); |
| 1096 __ SmiTag(result); | 1050 __ SmiTag(result); |
| 1097 break; | 1051 break; |
| 1098 default: | 1052 default: |
| 1099 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1053 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1100 __ movq(result, element_address); | 1054 __ movq(result, element_address); |
| 1101 break; | 1055 break; |
| 1102 } | 1056 } |
| 1103 } | 1057 } |
| 1104 | 1058 |
| (...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 | 2534 |
| 2581 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2535 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2582 UNIMPLEMENTED(); | 2536 UNIMPLEMENTED(); |
| 2583 } | 2537 } |
| 2584 | 2538 |
| 2585 } // namespace dart | 2539 } // namespace dart |
| 2586 | 2540 |
| 2587 #undef __ | 2541 #undef __ |
| 2588 | 2542 |
| 2589 #endif // defined TARGET_ARCH_X64 | 2543 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |