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_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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1135 __ SmiTag(result); | 1135 __ SmiTag(result); |
1136 break; | 1136 break; |
1137 default: | 1137 default: |
1138 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1138 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
1139 __ movq(result, element_address); | 1139 __ movq(result, element_address); |
1140 break; | 1140 break; |
1141 } | 1141 } |
1142 } | 1142 } |
1143 | 1143 |
1144 | 1144 |
| 1145 Representation LoadCodeUnitsInstr::representation() const { |
| 1146 switch (class_id()) { |
| 1147 case kOneByteStringCid: |
| 1148 case kTwoByteStringCid: |
| 1149 case kExternalOneByteStringCid: |
| 1150 case kExternalTwoByteStringCid: |
| 1151 return kTagged; |
| 1152 default: |
| 1153 UNIMPLEMENTED(); |
| 1154 return kTagged; |
| 1155 } |
| 1156 } |
| 1157 |
| 1158 |
| 1159 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, |
| 1160 bool opt) const { |
| 1161 const intptr_t kNumInputs = 2; |
| 1162 const intptr_t kNumTemps = 0; |
| 1163 LocationSummary* summary = new(isolate) LocationSummary( |
| 1164 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1165 summary->set_in(0, Location::RequiresRegister()); |
| 1166 // The smi index is either untagged (element size == 1), or it is left smi |
| 1167 // tagged (for all element sizes > 1). |
| 1168 summary->set_in(1, index_scale() == 1 ? Location::WritableRegister() |
| 1169 : Location::RequiresRegister()); |
| 1170 summary->set_out(0, Location::RequiresRegister()); |
| 1171 return summary; |
| 1172 } |
| 1173 |
| 1174 |
| 1175 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1176 const Register array = locs()->in(0).reg(); |
| 1177 const Location index = locs()->in(1); |
| 1178 |
| 1179 Address element_address = Assembler::ElementAddressForRegIndex( |
| 1180 IsExternal(), class_id(), index_scale(), array, index.reg()); |
| 1181 |
| 1182 if ((index_scale() == 1)) { |
| 1183 __ SmiUntag(index.reg()); |
| 1184 } |
| 1185 Register result = locs()->out(0).reg(); |
| 1186 switch (class_id()) { |
| 1187 case kOneByteStringCid: |
| 1188 case kExternalOneByteStringCid: |
| 1189 switch (element_count()) { |
| 1190 case 1: __ movzxb(result, element_address); break; |
| 1191 case 2: __ movzxw(result, element_address); break; |
| 1192 case 4: __ movl(result, element_address); break; |
| 1193 default: UNREACHABLE(); |
| 1194 } |
| 1195 __ SmiTag(result); |
| 1196 break; |
| 1197 case kTwoByteStringCid: |
| 1198 case kExternalTwoByteStringCid: |
| 1199 switch (element_count()) { |
| 1200 case 1: __ movzxw(result, element_address); break; |
| 1201 case 2: __ movl(result, element_address); break; |
| 1202 default: UNREACHABLE(); |
| 1203 } |
| 1204 __ SmiTag(result); |
| 1205 break; |
| 1206 default: |
| 1207 UNREACHABLE(); |
| 1208 break; |
| 1209 } |
| 1210 } |
| 1211 |
| 1212 |
1145 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1213 Representation StoreIndexedInstr::RequiredInputRepresentation( |
1146 intptr_t idx) const { | 1214 intptr_t idx) const { |
1147 if (idx == 0) return kNoRepresentation; | 1215 if (idx == 0) return kNoRepresentation; |
1148 if (idx == 1) return kTagged; | 1216 if (idx == 1) return kTagged; |
1149 ASSERT(idx == 2); | 1217 ASSERT(idx == 2); |
1150 switch (class_id_) { | 1218 switch (class_id_) { |
1151 case kArrayCid: | 1219 case kArrayCid: |
1152 case kOneByteStringCid: | 1220 case kOneByteStringCid: |
1153 case kTypedDataInt8ArrayCid: | 1221 case kTypedDataInt8ArrayCid: |
1154 case kTypedDataUint8ArrayCid: | 1222 case kTypedDataUint8ArrayCid: |
(...skipping 3382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4537 __ ReserveAlignedFrameSpace(0); | 4605 __ ReserveAlignedFrameSpace(0); |
4538 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 4606 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
4539 __ CallRuntime(TargetFunction(), InputCount()); | 4607 __ CallRuntime(TargetFunction(), InputCount()); |
4540 __ movaps(locs()->out(0).fpu_reg(), XMM0); | 4608 __ movaps(locs()->out(0).fpu_reg(), XMM0); |
4541 // Restore RSP. | 4609 // Restore RSP. |
4542 __ movq(RSP, locs()->temp(0).reg()); | 4610 __ movq(RSP, locs()->temp(0).reg()); |
4543 } | 4611 } |
4544 } | 4612 } |
4545 | 4613 |
4546 | 4614 |
| 4615 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( |
| 4616 Isolate* isolate, bool opt) const { |
| 4617 const intptr_t kNumTemps = 0; |
| 4618 LocationSummary* summary = new(isolate) LocationSummary( |
| 4619 isolate, InputCount(), kNumTemps, LocationSummary::kCall); |
| 4620 summary->set_in(0, Location::RegisterLocation(CallingConventions::kArg1Reg)); |
| 4621 summary->set_in(1, Location::RegisterLocation(CallingConventions::kArg2Reg)); |
| 4622 summary->set_in(2, Location::RegisterLocation(CallingConventions::kArg3Reg)); |
| 4623 summary->set_in(3, Location::RegisterLocation(CallingConventions::kArg4Reg)); |
| 4624 summary->set_out(0, Location::RegisterLocation(RAX)); |
| 4625 return summary; |
| 4626 } |
| 4627 |
| 4628 |
| 4629 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( |
| 4630 FlowGraphCompiler* compiler) { |
| 4631 |
| 4632 // Save RSP. R13 is chosen because it is callee saved so we do not need to |
| 4633 // back it up before calling into the runtime. |
| 4634 static const Register kSavedSPReg = R13; |
| 4635 __ movq(kSavedSPReg, RSP); |
| 4636 __ ReserveAlignedFrameSpace(0); |
| 4637 |
| 4638 // Call the function. Parameters are already in their correct spots. |
| 4639 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); |
| 4640 |
| 4641 // Restore RSP. |
| 4642 __ movq(RSP, kSavedSPReg); |
| 4643 } |
| 4644 |
| 4645 |
4547 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 4646 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, |
4548 bool opt) const { | 4647 bool opt) const { |
4549 const intptr_t kNumInputs = 1; | 4648 const intptr_t kNumInputs = 1; |
4550 return LocationSummary::Make(isolate, | 4649 return LocationSummary::Make(isolate, |
4551 kNumInputs, | 4650 kNumInputs, |
4552 Location::SameAsFirstInput(), | 4651 Location::SameAsFirstInput(), |
4553 LocationSummary::kNoCall); | 4652 LocationSummary::kNoCall); |
4554 } | 4653 } |
4555 | 4654 |
4556 | 4655 |
(...skipping 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6212 } | 6311 } |
6213 | 6312 |
6214 // We can fall through if the successor is the next block in the list. | 6313 // We can fall through if the successor is the next block in the list. |
6215 // Otherwise, we need a jump. | 6314 // Otherwise, we need a jump. |
6216 if (!compiler->CanFallThroughTo(successor())) { | 6315 if (!compiler->CanFallThroughTo(successor())) { |
6217 __ jmp(compiler->GetJumpLabel(successor())); | 6316 __ jmp(compiler->GetJumpLabel(successor())); |
6218 } | 6317 } |
6219 } | 6318 } |
6220 | 6319 |
6221 | 6320 |
| 6321 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, |
| 6322 bool opt) const { |
| 6323 const intptr_t kNumInputs = 1; |
| 6324 const intptr_t kNumTemps = 1; |
| 6325 |
| 6326 LocationSummary* summary = new(isolate) LocationSummary( |
| 6327 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6328 |
| 6329 summary->set_in(0, Location::RequiresRegister()); |
| 6330 summary->set_temp(0, Location::RequiresRegister()); |
| 6331 |
| 6332 return summary; |
| 6333 } |
| 6334 |
| 6335 |
| 6336 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6337 Register offset_reg = locs()->in(0).reg(); |
| 6338 Register target_address_reg = locs()->temp_slot(0)->reg(); |
| 6339 |
| 6340 // Load from [current frame pointer] + kPcMarkerSlotFromFp. |
| 6341 __ movq(target_address_reg, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); |
| 6342 |
| 6343 // Calculate the final absolute address. |
| 6344 __ SmiUntag(offset_reg); |
| 6345 __ addq(target_address_reg, offset_reg); |
| 6346 |
| 6347 // Jump to the absolute address. |
| 6348 __ jmp(target_address_reg); |
| 6349 } |
| 6350 |
6222 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 6351 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, |
6223 bool opt) const { | 6352 bool opt) const { |
6224 const intptr_t kNumInputs = 2; | 6353 const intptr_t kNumInputs = 2; |
6225 const intptr_t kNumTemps = 0; | 6354 const intptr_t kNumTemps = 0; |
6226 if (needs_number_check()) { | 6355 if (needs_number_check()) { |
6227 LocationSummary* locs = new(isolate) LocationSummary( | 6356 LocationSummary* locs = new(isolate) LocationSummary( |
6228 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 6357 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
6229 locs->set_in(0, Location::RegisterLocation(RAX)); | 6358 locs->set_in(0, Location::RegisterLocation(RAX)); |
6230 locs->set_in(1, Location::RegisterLocation(RCX)); | 6359 locs->set_in(1, Location::RegisterLocation(RCX)); |
6231 locs->set_out(0, Location::RegisterLocation(RAX)); | 6360 locs->set_out(0, Location::RegisterLocation(RAX)); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6403 __ movq(R10, Immediate(kInvalidObjectPointer)); | 6532 __ movq(R10, Immediate(kInvalidObjectPointer)); |
6404 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 6533 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
6405 #endif | 6534 #endif |
6406 } | 6535 } |
6407 | 6536 |
6408 } // namespace dart | 6537 } // namespace dart |
6409 | 6538 |
6410 #undef __ | 6539 #undef __ |
6411 | 6540 |
6412 #endif // defined TARGET_ARCH_X64 | 6541 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |