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 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 911 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
912 __ movq(R10, Immediate(NativeArguments::ComputeArgcTag(function()))); | 912 __ movq(R10, Immediate(NativeArguments::ComputeArgcTag(function()))); |
913 compiler->GenerateCall(token_pos(), | 913 compiler->GenerateCall(token_pos(), |
914 &StubCode::CallNativeCFunctionLabel(), | 914 &StubCode::CallNativeCFunctionLabel(), |
915 PcDescriptors::kOther, | 915 PcDescriptors::kOther, |
916 locs()); | 916 locs()); |
917 __ popq(result); | 917 __ popq(result); |
918 } | 918 } |
919 | 919 |
920 | 920 |
921 static bool CanBeImmediateIndex(Value* index) { | 921 static bool CanBeImmediateIndex(Value* index, intptr_t cid) { |
922 if (!index->definition()->IsConstant()) return false; | 922 if (!index->definition()->IsConstant()) return false; |
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 int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray); | 926 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); |
| 927 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); |
| 928 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; |
927 return Utils::IsInt(32, disp); | 929 return Utils::IsInt(32, disp); |
928 } | 930 } |
929 | 931 |
930 | 932 |
931 LocationSummary* StringCharCodeAtInstr::MakeLocationSummary() const { | 933 LocationSummary* StringCharCodeAtInstr::MakeLocationSummary() const { |
932 const intptr_t kNumInputs = 2; | 934 const intptr_t kNumInputs = 2; |
933 const intptr_t kNumTemps = 0; | 935 const intptr_t kNumTemps = 0; |
934 LocationSummary* locs = | 936 LocationSummary* locs = |
935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 937 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
936 locs->set_in(0, Location::RequiresRegister()); | 938 locs->set_in(0, Location::RequiresRegister()); |
937 // TODO(fschneider): Allow immediate operands for the index. | 939 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
938 locs->set_in(1, Location::RequiresRegister()); | 940 ? Location::RegisterOrSmiConstant(index()) |
| 941 : Location::RequiresRegister()); |
939 locs->set_out(Location::RequiresRegister()); | 942 locs->set_out(Location::RequiresRegister()); |
940 return locs; | 943 return locs; |
941 } | 944 } |
942 | 945 |
943 | 946 |
944 void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 947 void StringCharCodeAtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
945 Register str = locs()->in(0).reg(); | 948 Register str = locs()->in(0).reg(); |
946 Register index = locs()->in(1).reg(); | 949 Location index = locs()->in(1); |
947 Register result = locs()->out().reg(); | 950 Register result = locs()->out().reg(); |
948 | 951 |
949 ASSERT((class_id() == kOneByteStringCid) || | 952 ASSERT((class_id() == kOneByteStringCid) || |
950 (class_id() == kTwoByteStringCid)); | 953 (class_id() == kTwoByteStringCid)); |
| 954 |
| 955 FieldAddress element_address = index.IsRegister() ? |
| 956 FlowGraphCompiler::ElementAddressForRegIndex( |
| 957 class_id(), str, index.reg()) : |
| 958 FlowGraphCompiler::ElementAddressForIntIndex( |
| 959 class_id(), str, Smi::Cast(index.constant()).Value()); |
| 960 |
951 if (class_id() == kOneByteStringCid) { | 961 if (class_id() == kOneByteStringCid) { |
952 __ SmiUntag(index); | 962 if (index.IsRegister()) { |
953 __ movzxb(result, FieldAddress(str, | 963 __ SmiUntag(index.reg()); |
954 index, | 964 } |
955 TIMES_1, | 965 __ movzxb(result, element_address); |
956 OneByteString::data_offset())); | 966 if (index.IsRegister()) { |
957 __ SmiTag(index); // Retag index. | 967 __ SmiTag(index.reg()); // Retag index. |
| 968 } |
958 __ SmiTag(result); | 969 __ SmiTag(result); |
959 } else { | 970 } else { |
960 // Don't untag smi-index and use TIMES_1 for two byte strings. | 971 // Don't untag smi-index and use TIMES_1 for two byte strings. |
961 __ movzxw(result, FieldAddress(str, | 972 __ movzxw(result, element_address); |
962 index, | |
963 TIMES_1, | |
964 TwoByteString::data_offset())); | |
965 __ SmiTag(result); | 973 __ SmiTag(result); |
966 } | 974 } |
967 } | 975 } |
968 | 976 |
969 | 977 |
970 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 978 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { |
971 const intptr_t kNumInputs = 1; | 979 const intptr_t kNumInputs = 1; |
972 const intptr_t kNumTemps = 0; | 980 const intptr_t kNumTemps = 0; |
973 LocationSummary* locs = | 981 LocationSummary* locs = |
974 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 982 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 15 matching lines...) Expand all Loading... |
990 Symbols::kNullCharCodeSymbolOffset * kWordSize)); | 998 Symbols::kNullCharCodeSymbolOffset * kWordSize)); |
991 } | 999 } |
992 | 1000 |
993 | 1001 |
994 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1002 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
995 const intptr_t kNumInputs = 2; | 1003 const intptr_t kNumInputs = 2; |
996 const intptr_t kNumTemps = 0; | 1004 const intptr_t kNumTemps = 0; |
997 LocationSummary* locs = | 1005 LocationSummary* locs = |
998 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1006 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
999 locs->set_in(0, Location::RequiresRegister()); | 1007 locs->set_in(0, Location::RequiresRegister()); |
1000 locs->set_in(1, CanBeImmediateIndex(index()) | 1008 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1001 ? Location::RegisterOrConstant(index()) | 1009 ? Location::RegisterOrSmiConstant(index()) |
1002 : Location::RequiresRegister()); | 1010 : Location::RequiresRegister()); |
1003 if (representation() == kUnboxedDouble) { | 1011 if (representation() == kUnboxedDouble) { |
1004 locs->set_out(Location::RequiresXmmRegister()); | 1012 locs->set_out(Location::RequiresXmmRegister()); |
1005 } else { | 1013 } else { |
1006 locs->set_out(Location::RequiresRegister()); | 1014 locs->set_out(Location::RequiresRegister()); |
1007 } | 1015 } |
1008 return locs; | 1016 return locs; |
1009 } | 1017 } |
1010 | 1018 |
1011 | 1019 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 __ movq(result, element_address); | 1079 __ movq(result, element_address); |
1072 } | 1080 } |
1073 | 1081 |
1074 | 1082 |
1075 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1083 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
1076 const intptr_t kNumInputs = 3; | 1084 const intptr_t kNumInputs = 3; |
1077 const intptr_t numTemps = 0; | 1085 const intptr_t numTemps = 0; |
1078 LocationSummary* locs = | 1086 LocationSummary* locs = |
1079 new LocationSummary(kNumInputs, numTemps, LocationSummary::kNoCall); | 1087 new LocationSummary(kNumInputs, numTemps, LocationSummary::kNoCall); |
1080 locs->set_in(0, Location::RequiresRegister()); | 1088 locs->set_in(0, Location::RequiresRegister()); |
1081 locs->set_in(1, CanBeImmediateIndex(index()) | 1089 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
1082 ? Location::RegisterOrConstant(index()) | 1090 ? Location::RegisterOrSmiConstant(index()) |
1083 : Location::RequiresRegister()); | 1091 : Location::RequiresRegister()); |
1084 switch (class_id()) { | 1092 switch (class_id()) { |
1085 case kArrayCid: | 1093 case kArrayCid: |
1086 locs->set_in(2, ShouldEmitStoreBarrier() | 1094 locs->set_in(2, ShouldEmitStoreBarrier() |
1087 ? Location::WritableRegister() | 1095 ? Location::WritableRegister() |
1088 : Location::RegisterOrConstant(value())); | 1096 : Location::RegisterOrConstant(value())); |
1089 break; | 1097 break; |
1090 case kUint8ArrayCid: | 1098 case kUint8ArrayCid: |
1091 // TODO(fschneider): Add location constraint for byte registers (RAX, | 1099 // TODO(fschneider): Add location constraint for byte registers (RAX, |
1092 // RBX, RCX, RDX) instead of using a fixed register. | 1100 // RBX, RCX, RDX) instead of using a fixed register. |
(...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2496 | 2504 |
2497 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2505 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2498 UNIMPLEMENTED(); | 2506 UNIMPLEMENTED(); |
2499 } | 2507 } |
2500 | 2508 |
2501 } // namespace dart | 2509 } // namespace dart |
2502 | 2510 |
2503 #undef __ | 2511 #undef __ |
2504 | 2512 |
2505 #endif // defined TARGET_ARCH_X64 | 2513 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |