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 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 __ SmiTag(result); | 1087 __ SmiTag(result); |
1088 break; | 1088 break; |
1089 default: | 1089 default: |
1090 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1090 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
1091 __ movq(result, element_address); | 1091 __ movq(result, element_address); |
1092 break; | 1092 break; |
1093 } | 1093 } |
1094 } | 1094 } |
1095 | 1095 |
1096 | 1096 |
| 1097 Representation LoadCodeUnitsInstr::representation() const { |
| 1098 switch (class_id()) { |
| 1099 case kOneByteStringCid: |
| 1100 case kTwoByteStringCid: |
| 1101 case kExternalOneByteStringCid: |
| 1102 case kExternalTwoByteStringCid: |
| 1103 return kTagged; |
| 1104 default: |
| 1105 UNIMPLEMENTED(); |
| 1106 return kTagged; |
| 1107 } |
| 1108 } |
| 1109 |
| 1110 |
| 1111 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, |
| 1112 bool opt) const { |
| 1113 const intptr_t kNumInputs = 2; |
| 1114 const intptr_t kNumTemps = 0; |
| 1115 LocationSummary* summary = new(isolate) LocationSummary( |
| 1116 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1117 summary->set_in(0, Location::RequiresRegister()); |
| 1118 // The smi index is either untagged (element size == 1), or it is left smi |
| 1119 // tagged (for all element sizes > 1). |
| 1120 summary->set_in(1, index_scale() == 1 ? Location::WritableRegister() |
| 1121 : Location::RequiresRegister()); |
| 1122 summary->set_out(0, Location::RequiresRegister()); |
| 1123 return summary; |
| 1124 } |
| 1125 |
| 1126 |
| 1127 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1128 const Register array = locs()->in(0).reg(); |
| 1129 const Location index = locs()->in(1); |
| 1130 |
| 1131 Address element_address = Assembler::ElementAddressForRegIndex( |
| 1132 IsExternal(), class_id(), index_scale(), array, index.reg()); |
| 1133 |
| 1134 if ((index_scale() == 1)) { |
| 1135 __ SmiUntag(index.reg()); |
| 1136 } |
| 1137 Register result = locs()->out(0).reg(); |
| 1138 switch (class_id()) { |
| 1139 case kOneByteStringCid: |
| 1140 case kExternalOneByteStringCid: |
| 1141 switch (element_count()) { |
| 1142 case 1: __ movzxb(result, element_address); break; |
| 1143 case 2: __ movzxw(result, element_address); break; |
| 1144 case 4: __ movl(result, element_address); break; |
| 1145 default: UNREACHABLE(); |
| 1146 } |
| 1147 __ SmiTag(result); |
| 1148 break; |
| 1149 case kTwoByteStringCid: |
| 1150 case kExternalTwoByteStringCid: |
| 1151 switch (element_count()) { |
| 1152 case 1: __ movzxw(result, element_address); break; |
| 1153 case 2: __ movl(result, element_address); break; |
| 1154 default: UNREACHABLE(); |
| 1155 } |
| 1156 __ SmiTag(result); |
| 1157 break; |
| 1158 default: |
| 1159 UNREACHABLE(); |
| 1160 break; |
| 1161 } |
| 1162 } |
| 1163 |
| 1164 |
1097 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1165 Representation StoreIndexedInstr::RequiredInputRepresentation( |
1098 intptr_t idx) const { | 1166 intptr_t idx) const { |
1099 if (idx == 0) return kNoRepresentation; | 1167 if (idx == 0) return kNoRepresentation; |
1100 if (idx == 1) return kTagged; | 1168 if (idx == 1) return kTagged; |
1101 ASSERT(idx == 2); | 1169 ASSERT(idx == 2); |
1102 switch (class_id_) { | 1170 switch (class_id_) { |
1103 case kArrayCid: | 1171 case kArrayCid: |
1104 case kOneByteStringCid: | 1172 case kOneByteStringCid: |
1105 case kTypedDataInt8ArrayCid: | 1173 case kTypedDataInt8ArrayCid: |
1106 case kTypedDataUint8ArrayCid: | 1174 case kTypedDataUint8ArrayCid: |
(...skipping 3372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4479 __ ReserveAlignedFrameSpace(0); | 4547 __ ReserveAlignedFrameSpace(0); |
4480 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 4548 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
4481 __ CallRuntime(TargetFunction(), InputCount()); | 4549 __ CallRuntime(TargetFunction(), InputCount()); |
4482 __ movaps(locs()->out(0).fpu_reg(), XMM0); | 4550 __ movaps(locs()->out(0).fpu_reg(), XMM0); |
4483 // Restore RSP. | 4551 // Restore RSP. |
4484 __ movq(RSP, locs()->temp(0).reg()); | 4552 __ movq(RSP, locs()->temp(0).reg()); |
4485 } | 4553 } |
4486 } | 4554 } |
4487 | 4555 |
4488 | 4556 |
| 4557 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( |
| 4558 Isolate* isolate, bool opt) const { |
| 4559 const intptr_t kNumTemps = 0; |
| 4560 LocationSummary* summary = new(isolate) LocationSummary( |
| 4561 isolate, InputCount(), kNumTemps, LocationSummary::kCall); |
| 4562 summary->set_in(0, Location::RegisterLocation(CallingConventions::kArg1Reg)); |
| 4563 summary->set_in(1, Location::RegisterLocation(CallingConventions::kArg2Reg)); |
| 4564 summary->set_in(2, Location::RegisterLocation(CallingConventions::kArg3Reg)); |
| 4565 summary->set_in(3, Location::RegisterLocation(CallingConventions::kArg4Reg)); |
| 4566 summary->set_out(0, Location::RegisterLocation(RAX)); |
| 4567 return summary; |
| 4568 } |
| 4569 |
| 4570 |
| 4571 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( |
| 4572 FlowGraphCompiler* compiler) { |
| 4573 |
| 4574 // Save RSP. R13 is chosen because it is callee saved so we do not need to |
| 4575 // back it up before calling into the runtime. |
| 4576 static const Register kSavedSPReg = R13; |
| 4577 __ movq(kSavedSPReg, RSP); |
| 4578 __ ReserveAlignedFrameSpace(0); |
| 4579 |
| 4580 // Call the function. Parameters are already in their correct spots. |
| 4581 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); |
| 4582 |
| 4583 // Restore RSP. |
| 4584 __ movq(RSP, kSavedSPReg); |
| 4585 } |
| 4586 |
| 4587 |
4489 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 4588 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, |
4490 bool opt) const { | 4589 bool opt) const { |
4491 const intptr_t kNumInputs = 1; | 4590 const intptr_t kNumInputs = 1; |
4492 return LocationSummary::Make(isolate, | 4591 return LocationSummary::Make(isolate, |
4493 kNumInputs, | 4592 kNumInputs, |
4494 Location::SameAsFirstInput(), | 4593 Location::SameAsFirstInput(), |
4495 LocationSummary::kNoCall); | 4594 LocationSummary::kNoCall); |
4496 } | 4595 } |
4497 | 4596 |
4498 | 4597 |
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5738 } | 5837 } |
5739 | 5838 |
5740 // We can fall through if the successor is the next block in the list. | 5839 // We can fall through if the successor is the next block in the list. |
5741 // Otherwise, we need a jump. | 5840 // Otherwise, we need a jump. |
5742 if (!compiler->CanFallThroughTo(successor())) { | 5841 if (!compiler->CanFallThroughTo(successor())) { |
5743 __ jmp(compiler->GetJumpLabel(successor())); | 5842 __ jmp(compiler->GetJumpLabel(successor())); |
5744 } | 5843 } |
5745 } | 5844 } |
5746 | 5845 |
5747 | 5846 |
| 5847 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, |
| 5848 bool opt) const { |
| 5849 const intptr_t kNumInputs = 1; |
| 5850 const intptr_t kNumTemps = 1; |
| 5851 |
| 5852 LocationSummary* summary = new(isolate) LocationSummary( |
| 5853 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5854 |
| 5855 summary->set_in(0, Location::RequiresRegister()); |
| 5856 summary->set_temp(0, Location::RequiresRegister()); |
| 5857 |
| 5858 return summary; |
| 5859 } |
| 5860 |
| 5861 |
| 5862 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5863 Register offset_reg = locs()->in(0).reg(); |
| 5864 Register target_address_reg = locs()->temp_slot(0)->reg(); |
| 5865 |
| 5866 // Load from [current frame pointer] + kPcMarkerSlotFromFp. |
| 5867 __ movq(target_address_reg, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); |
| 5868 |
| 5869 // Calculate the final absolute address. |
| 5870 __ SmiUntag(offset_reg); |
| 5871 __ addq(target_address_reg, offset_reg); |
| 5872 |
| 5873 // Jump to the absolute address. |
| 5874 __ jmp(target_address_reg); |
| 5875 } |
| 5876 |
5748 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 5877 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, |
5749 bool opt) const { | 5878 bool opt) const { |
5750 const intptr_t kNumInputs = 2; | 5879 const intptr_t kNumInputs = 2; |
5751 const intptr_t kNumTemps = 0; | 5880 const intptr_t kNumTemps = 0; |
5752 if (needs_number_check()) { | 5881 if (needs_number_check()) { |
5753 LocationSummary* locs = new(isolate) LocationSummary( | 5882 LocationSummary* locs = new(isolate) LocationSummary( |
5754 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 5883 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
5755 locs->set_in(0, Location::RegisterLocation(RAX)); | 5884 locs->set_in(0, Location::RegisterLocation(RAX)); |
5756 locs->set_in(1, Location::RegisterLocation(RCX)); | 5885 locs->set_in(1, Location::RegisterLocation(RCX)); |
5757 locs->set_out(0, Location::RegisterLocation(RAX)); | 5886 locs->set_out(0, Location::RegisterLocation(RAX)); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5929 __ movq(R10, Immediate(kInvalidObjectPointer)); | 6058 __ movq(R10, Immediate(kInvalidObjectPointer)); |
5930 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 6059 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
5931 #endif | 6060 #endif |
5932 } | 6061 } |
5933 | 6062 |
5934 } // namespace dart | 6063 } // namespace dart |
5935 | 6064 |
5936 #undef __ | 6065 #undef __ |
5937 | 6066 |
5938 #endif // defined TARGET_ARCH_X64 | 6067 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |