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 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 return; | 1067 return; |
1068 } | 1068 } |
1069 | 1069 |
1070 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1070 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
1071 __ movq(result, element_address); | 1071 __ movq(result, element_address); |
1072 } | 1072 } |
1073 | 1073 |
1074 | 1074 |
1075 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1075 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
1076 const intptr_t kNumInputs = 3; | 1076 const intptr_t kNumInputs = 3; |
1077 const intptr_t kNumTemps = class_id() == kFloat32ArrayCid ? 1 : 0; | 1077 const intptr_t numTemps = 0; |
1078 LocationSummary* locs = | 1078 LocationSummary* locs = |
1079 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1079 new LocationSummary(kNumInputs, numTemps, LocationSummary::kNoCall); |
1080 if (class_id() == kFloat32ArrayCid) { | |
1081 locs->set_temp(0, Location::RequiresXmmRegister()); | |
1082 } | |
1083 locs->set_in(0, Location::RequiresRegister()); | 1080 locs->set_in(0, Location::RequiresRegister()); |
1084 locs->set_in(1, CanBeImmediateIndex(index()) | 1081 locs->set_in(1, CanBeImmediateIndex(index()) |
1085 ? Location::RegisterOrConstant(index()) | 1082 ? Location::RegisterOrConstant(index()) |
1086 : Location::RequiresRegister()); | 1083 : Location::RequiresRegister()); |
1087 if (RequiredInputRepresentation(2) == kUnboxedDouble) { | 1084 switch (class_id()) { |
1088 // TODO(srdjan): Support Float64 constants. | 1085 case kArrayCid: |
1089 locs->set_in(2, Location::RequiresXmmRegister()); | 1086 locs->set_in(2, ShouldEmitStoreBarrier() |
1090 } else { | 1087 ? Location::WritableRegister() |
1091 locs->set_in(2, ShouldEmitStoreBarrier() | 1088 : Location::RegisterOrConstant(value())); |
1092 ? Location::WritableRegister() | 1089 break; |
1093 : Location::RegisterOrConstant(value())); | 1090 case kUint8ArrayCid: |
| 1091 // TODO(fschneider): Add location constraint for byte registers (RAX, |
| 1092 // RBX, RCX, RDX) instead of using a fixed register. |
| 1093 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); |
| 1094 break; |
| 1095 case kFloat32ArrayCid: |
| 1096 // Need temp register for float-to-double conversion. |
| 1097 locs->AddTemp(Location::RequiresXmmRegister()); |
| 1098 // Fall through. |
| 1099 case kFloat64ArrayCid: |
| 1100 // TODO(srdjan): Support Float64 constants. |
| 1101 locs->set_in(2, Location::RequiresXmmRegister()); |
| 1102 break; |
| 1103 default: |
| 1104 UNREACHABLE(); |
| 1105 return NULL; |
1094 } | 1106 } |
1095 return locs; | 1107 return locs; |
1096 } | 1108 } |
1097 | 1109 |
1098 | 1110 |
1099 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1111 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1100 Register array = locs()->in(0).reg(); | 1112 Register array = locs()->in(0).reg(); |
1101 Location index = locs()->in(1); | 1113 Location index = locs()->in(1); |
| 1114 |
1102 FieldAddress element_address = index.IsRegister() ? | 1115 FieldAddress element_address = index.IsRegister() ? |
1103 FlowGraphCompiler::ElementAddressForRegIndex( | 1116 FlowGraphCompiler::ElementAddressForRegIndex( |
1104 class_id(), array, index.reg()) : | 1117 class_id(), array, index.reg()) : |
1105 FlowGraphCompiler::ElementAddressForIntIndex( | 1118 FlowGraphCompiler::ElementAddressForIntIndex( |
1106 class_id(), array, Smi::Cast(index.constant()).Value()); | 1119 class_id(), array, Smi::Cast(index.constant()).Value()); |
1107 | 1120 |
1108 if (class_id() == kFloat32ArrayCid) { | 1121 switch (class_id()) { |
1109 // Convert to single precision. | 1122 case kArrayCid: |
1110 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg()); | 1123 if (ShouldEmitStoreBarrier()) { |
1111 // Store. | 1124 Register value = locs()->in(2).reg(); |
1112 __ movss(element_address, locs()->temp(0).xmm_reg()); | 1125 __ StoreIntoObject(array, element_address, value); |
1113 return; | 1126 } else if (locs()->in(2).IsConstant()) { |
1114 } | 1127 const Object& constant = locs()->in(2).constant(); |
1115 | 1128 __ StoreObject(element_address, constant); |
1116 if (class_id() == kFloat64ArrayCid) { | 1129 } else { |
1117 __ movsd(element_address, locs()->in(2).xmm_reg()); | 1130 Register value = locs()->in(2).reg(); |
1118 return; | 1131 __ StoreIntoObjectNoBarrier(array, element_address, value); |
1119 } | 1132 } |
1120 | 1133 break; |
1121 ASSERT(class_id() == kArrayCid); | 1134 case kUint8ArrayCid: |
1122 if (ShouldEmitStoreBarrier()) { | 1135 if (index.IsRegister()) { |
1123 Register value = locs()->in(2).reg(); | 1136 __ SmiUntag(index.reg()); |
1124 __ StoreIntoObject(array, element_address, value); | 1137 } |
1125 return; | 1138 if (locs()->in(2).IsConstant()) { |
1126 } | 1139 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
1127 | 1140 __ movb(element_address, |
1128 if (locs()->in(2).IsConstant()) { | 1141 Immediate(static_cast<int8_t>(constant.Value()))); |
1129 const Object& constant = locs()->in(2).constant(); | 1142 } else { |
1130 __ StoreObject(element_address, constant); | 1143 ASSERT(locs()->in(2).reg() == RAX); |
1131 } else { | 1144 __ SmiUntag(RAX); |
1132 Register value = locs()->in(2).reg(); | 1145 __ movb(element_address, RAX); |
1133 __ StoreIntoObjectNoBarrier(array, element_address, value); | 1146 } |
| 1147 if (index.IsRegister()) { |
| 1148 __ SmiTag(index.reg()); // Re-tag. |
| 1149 } |
| 1150 break; |
| 1151 case kFloat32ArrayCid: |
| 1152 // Convert to single precision. |
| 1153 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg()); |
| 1154 // Store. |
| 1155 __ movss(element_address, locs()->temp(0).xmm_reg()); |
| 1156 break; |
| 1157 case kFloat64ArrayCid: |
| 1158 __ movsd(element_address, locs()->in(2).xmm_reg()); |
| 1159 break; |
| 1160 default: |
| 1161 UNREACHABLE(); |
1134 } | 1162 } |
1135 } | 1163 } |
1136 | 1164 |
1137 | 1165 |
1138 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1166 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
1139 const intptr_t kNumInputs = 2; | 1167 const intptr_t kNumInputs = 2; |
1140 const intptr_t num_temps = 0; | 1168 const intptr_t num_temps = 0; |
1141 LocationSummary* summary = | 1169 LocationSummary* summary = |
1142 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); | 1170 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
1143 summary->set_in(0, Location::RequiresRegister()); | 1171 summary->set_in(0, Location::RequiresRegister()); |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2441 | 2469 |
2442 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2470 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2443 UNIMPLEMENTED(); | 2471 UNIMPLEMENTED(); |
2444 } | 2472 } |
2445 | 2473 |
2446 } // namespace dart | 2474 } // namespace dart |
2447 | 2475 |
2448 #undef __ | 2476 #undef __ |
2449 | 2477 |
2450 #endif // defined TARGET_ARCH_X64 | 2478 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |