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 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 __ SmiTag(result); | 1124 __ SmiTag(result); |
1125 break; | 1125 break; |
1126 default: | 1126 default: |
1127 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1127 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
1128 __ movq(result, element_address); | 1128 __ movq(result, element_address); |
1129 break; | 1129 break; |
1130 } | 1130 } |
1131 } | 1131 } |
1132 | 1132 |
1133 | 1133 |
| 1134 Representation LoadCodeUnitsInstr::representation() const { |
| 1135 switch (class_id()) { |
| 1136 case kOneByteStringCid: |
| 1137 case kTwoByteStringCid: |
| 1138 case kExternalOneByteStringCid: |
| 1139 case kExternalTwoByteStringCid: |
| 1140 return kTagged; |
| 1141 default: |
| 1142 UNIMPLEMENTED(); |
| 1143 return kTagged; |
| 1144 } |
| 1145 } |
| 1146 |
| 1147 |
| 1148 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, |
| 1149 bool opt) const { |
| 1150 const intptr_t kNumInputs = 2; |
| 1151 const intptr_t kNumTemps = 0; |
| 1152 LocationSummary* summary = new(isolate) LocationSummary( |
| 1153 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1154 summary->set_in(0, Location::RequiresRegister()); |
| 1155 // The smi index is either untagged (element size == 1), or it is left smi |
| 1156 // tagged (for all element sizes > 1). |
| 1157 summary->set_in(1, index_scale() == 1 ? Location::WritableRegister() |
| 1158 : Location::RequiresRegister()); |
| 1159 summary->set_out(0, Location::RequiresRegister()); |
| 1160 return summary; |
| 1161 } |
| 1162 |
| 1163 |
| 1164 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1165 const Register array = locs()->in(0).reg(); |
| 1166 const Location index = locs()->in(1); |
| 1167 |
| 1168 Address element_address = Assembler::ElementAddressForRegIndex( |
| 1169 IsExternal(), class_id(), index_scale(), array, index.reg()); |
| 1170 |
| 1171 if ((index_scale() == 1)) { |
| 1172 __ SmiUntag(index.reg()); |
| 1173 } |
| 1174 Register result = locs()->out(0).reg(); |
| 1175 switch (class_id()) { |
| 1176 case kOneByteStringCid: |
| 1177 case kExternalOneByteStringCid: |
| 1178 switch (element_count()) { |
| 1179 case 1: __ movzxb(result, element_address); break; |
| 1180 case 2: __ movzxw(result, element_address); break; |
| 1181 case 4: __ movl(result, element_address); break; |
| 1182 default: UNREACHABLE(); |
| 1183 } |
| 1184 __ SmiTag(result); |
| 1185 break; |
| 1186 case kTwoByteStringCid: |
| 1187 case kExternalTwoByteStringCid: |
| 1188 switch (element_count()) { |
| 1189 case 1: __ movzxw(result, element_address); break; |
| 1190 case 2: __ movl(result, element_address); break; |
| 1191 default: UNREACHABLE(); |
| 1192 } |
| 1193 __ SmiTag(result); |
| 1194 break; |
| 1195 default: |
| 1196 UNREACHABLE(); |
| 1197 break; |
| 1198 } |
| 1199 } |
| 1200 |
| 1201 |
1134 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1202 Representation StoreIndexedInstr::RequiredInputRepresentation( |
1135 intptr_t idx) const { | 1203 intptr_t idx) const { |
1136 if (idx == 0) return kNoRepresentation; | 1204 if (idx == 0) return kNoRepresentation; |
1137 if (idx == 1) return kTagged; | 1205 if (idx == 1) return kTagged; |
1138 ASSERT(idx == 2); | 1206 ASSERT(idx == 2); |
1139 switch (class_id_) { | 1207 switch (class_id_) { |
1140 case kArrayCid: | 1208 case kArrayCid: |
1141 case kOneByteStringCid: | 1209 case kOneByteStringCid: |
1142 case kTypedDataInt8ArrayCid: | 1210 case kTypedDataInt8ArrayCid: |
1143 case kTypedDataUint8ArrayCid: | 1211 case kTypedDataUint8ArrayCid: |
(...skipping 3382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 __ ReserveAlignedFrameSpace(0); | 4594 __ ReserveAlignedFrameSpace(0); |
4527 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 4595 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
4528 __ CallRuntime(TargetFunction(), InputCount()); | 4596 __ CallRuntime(TargetFunction(), InputCount()); |
4529 __ movaps(locs()->out(0).fpu_reg(), XMM0); | 4597 __ movaps(locs()->out(0).fpu_reg(), XMM0); |
4530 // Restore RSP. | 4598 // Restore RSP. |
4531 __ movq(RSP, locs()->temp(0).reg()); | 4599 __ movq(RSP, locs()->temp(0).reg()); |
4532 } | 4600 } |
4533 } | 4601 } |
4534 | 4602 |
4535 | 4603 |
| 4604 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( |
| 4605 Isolate* isolate, bool opt) const { |
| 4606 const intptr_t kNumTemps = 0; |
| 4607 LocationSummary* summary = new(isolate) LocationSummary( |
| 4608 isolate, InputCount(), kNumTemps, LocationSummary::kCall); |
| 4609 summary->set_in(0, Location::RegisterLocation(CallingConventions::kArg1Reg)); |
| 4610 summary->set_in(1, Location::RegisterLocation(CallingConventions::kArg2Reg)); |
| 4611 summary->set_in(2, Location::RegisterLocation(CallingConventions::kArg3Reg)); |
| 4612 summary->set_in(3, Location::RegisterLocation(CallingConventions::kArg4Reg)); |
| 4613 summary->set_out(0, Location::RegisterLocation(RAX)); |
| 4614 return summary; |
| 4615 } |
| 4616 |
| 4617 |
| 4618 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( |
| 4619 FlowGraphCompiler* compiler) { |
| 4620 |
| 4621 // Save RSP. R13 is chosen because it is callee saved so we do not need to |
| 4622 // back it up before calling into the runtime. |
| 4623 static const Register kSavedSPReg = R13; |
| 4624 __ movq(kSavedSPReg, RSP); |
| 4625 __ ReserveAlignedFrameSpace(0); |
| 4626 |
| 4627 // Call the function. Parameters are already in their correct spots. |
| 4628 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); |
| 4629 |
| 4630 // Restore RSP. |
| 4631 __ movq(RSP, kSavedSPReg); |
| 4632 } |
| 4633 |
| 4634 |
4536 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 4635 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, |
4537 bool opt) const { | 4636 bool opt) const { |
4538 const intptr_t kNumInputs = 1; | 4637 const intptr_t kNumInputs = 1; |
4539 return LocationSummary::Make(isolate, | 4638 return LocationSummary::Make(isolate, |
4540 kNumInputs, | 4639 kNumInputs, |
4541 Location::SameAsFirstInput(), | 4640 Location::SameAsFirstInput(), |
4542 LocationSummary::kNoCall); | 4641 LocationSummary::kNoCall); |
4543 } | 4642 } |
4544 | 4643 |
4545 | 4644 |
(...skipping 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6201 } | 6300 } |
6202 | 6301 |
6203 // We can fall through if the successor is the next block in the list. | 6302 // We can fall through if the successor is the next block in the list. |
6204 // Otherwise, we need a jump. | 6303 // Otherwise, we need a jump. |
6205 if (!compiler->CanFallThroughTo(successor())) { | 6304 if (!compiler->CanFallThroughTo(successor())) { |
6206 __ jmp(compiler->GetJumpLabel(successor())); | 6305 __ jmp(compiler->GetJumpLabel(successor())); |
6207 } | 6306 } |
6208 } | 6307 } |
6209 | 6308 |
6210 | 6309 |
| 6310 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, |
| 6311 bool opt) const { |
| 6312 const intptr_t kNumInputs = 1; |
| 6313 const intptr_t kNumTemps = 1; |
| 6314 |
| 6315 LocationSummary* summary = new(isolate) LocationSummary( |
| 6316 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6317 |
| 6318 summary->set_in(0, Location::RequiresRegister()); |
| 6319 summary->set_temp(0, Location::RequiresRegister()); |
| 6320 |
| 6321 return summary; |
| 6322 } |
| 6323 |
| 6324 |
| 6325 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6326 Register offset_reg = locs()->in(0).reg(); |
| 6327 Register target_address_reg = locs()->temp_slot(0)->reg(); |
| 6328 |
| 6329 // Load from [current frame pointer] + kPcMarkerSlotFromFp. |
| 6330 __ movq(target_address_reg, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); |
| 6331 |
| 6332 // Calculate the final absolute address. |
| 6333 __ SmiUntag(offset_reg); |
| 6334 __ addq(target_address_reg, offset_reg); |
| 6335 |
| 6336 // Jump to the absolute address. |
| 6337 __ jmp(target_address_reg); |
| 6338 } |
| 6339 |
6211 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 6340 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, |
6212 bool opt) const { | 6341 bool opt) const { |
6213 const intptr_t kNumInputs = 2; | 6342 const intptr_t kNumInputs = 2; |
6214 const intptr_t kNumTemps = 0; | 6343 const intptr_t kNumTemps = 0; |
6215 if (needs_number_check()) { | 6344 if (needs_number_check()) { |
6216 LocationSummary* locs = new(isolate) LocationSummary( | 6345 LocationSummary* locs = new(isolate) LocationSummary( |
6217 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 6346 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
6218 locs->set_in(0, Location::RegisterLocation(RAX)); | 6347 locs->set_in(0, Location::RegisterLocation(RAX)); |
6219 locs->set_in(1, Location::RegisterLocation(RCX)); | 6348 locs->set_in(1, Location::RegisterLocation(RCX)); |
6220 locs->set_out(0, Location::RegisterLocation(RAX)); | 6349 locs->set_out(0, Location::RegisterLocation(RAX)); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6392 __ movq(R10, Immediate(kInvalidObjectPointer)); | 6521 __ movq(R10, Immediate(kInvalidObjectPointer)); |
6393 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 6522 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
6394 #endif | 6523 #endif |
6395 } | 6524 } |
6396 | 6525 |
6397 } // namespace dart | 6526 } // namespace dart |
6398 | 6527 |
6399 #undef __ | 6528 #undef __ |
6400 | 6529 |
6401 #endif // defined TARGET_ARCH_X64 | 6530 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |