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 CompileType LoadCodeUnitsInstr::ComputeType() const { | |
1098 switch (class_id()) { | |
1099 case kOneByteStringCid: | |
1100 case kTwoByteStringCid: | |
1101 case kExternalOneByteStringCid: | |
1102 case kExternalTwoByteStringCid: | |
1103 return CompileType::FromCid(kSmiCid); | |
1104 default: | |
1105 UNIMPLEMENTED(); | |
1106 return CompileType::Dynamic(); | |
1107 } | |
1108 } | |
1109 | |
1110 | |
1111 Representation LoadCodeUnitsInstr::representation() const { | |
1112 switch (class_id()) { | |
1113 case kOneByteStringCid: | |
1114 case kTwoByteStringCid: | |
1115 case kExternalOneByteStringCid: | |
1116 case kExternalTwoByteStringCid: | |
1117 return kTagged; | |
1118 default: | |
1119 UNIMPLEMENTED(); | |
1120 return kTagged; | |
1121 } | |
1122 } | |
1123 | |
1124 | |
1125 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, | |
1126 bool opt) const { | |
1127 const intptr_t kNumInputs = 2; | |
1128 const intptr_t kNumTemps = 0; | |
1129 LocationSummary* locs = new(isolate) LocationSummary( | |
1130 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1131 locs->set_in(0, Location::RequiresRegister()); | |
1132 // The smi index is either untagged (element size == 1), or it is left smi | |
1133 // tagged (for all element sizes > 1). | |
1134 if (index_scale() == 1) { | |
1135 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | |
1136 ? Location::Constant(index()->definition()->AsConstant()) | |
1137 : Location::WritableRegister()); | |
1138 } else { | |
1139 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | |
1140 ? Location::Constant(index()->definition()->AsConstant()) | |
1141 : Location::RequiresRegister()); | |
1142 } | |
1143 | |
1144 locs->set_out(0, Location::RequiresRegister()); | |
1145 return locs; | |
1146 } | |
1147 | |
1148 | |
1149 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
1150 const Register array = locs()->in(0).reg(); | |
1151 const Location index = locs()->in(1); | |
1152 | |
1153 Address element_address = index.IsRegister() | |
1154 ? Assembler::ElementAddressForRegIndex( | |
1155 IsExternal(), class_id(), index_scale(), array, index.reg()) | |
1156 : Assembler::ElementAddressForIntIndex( | |
1157 IsExternal(), class_id(), index_scale(), | |
1158 array, Smi::Cast(index.constant()).Value()); | |
1159 | |
1160 if ((index_scale() == 1) && index.IsRegister()) { | |
1161 __ SmiUntag(index.reg()); | |
1162 } | |
1163 Register result = locs()->out(0).reg(); | |
1164 switch (class_id()) { | |
1165 case kOneByteStringCid: | |
1166 case kExternalOneByteStringCid: | |
1167 switch (element_count()) { | |
1168 case 1: __ movzxb(result, element_address); break; | |
1169 case 2: __ movzxw(result, element_address); break; | |
1170 case 4: __ movl(result, element_address); break; | |
1171 default: UNREACHABLE(); | |
1172 } | |
1173 __ SmiTag(result); | |
1174 break; | |
1175 case kTwoByteStringCid: | |
1176 case kExternalTwoByteStringCid: | |
1177 switch (element_count()) { | |
1178 case 1: __ movzxw(result, element_address); break; | |
1179 case 2: __ movl(result, element_address); break; | |
1180 default: UNREACHABLE(); | |
1181 } | |
1182 __ SmiTag(result); | |
1183 break; | |
1184 default: | |
1185 UNREACHABLE(); | |
1186 break; | |
1187 } | |
1188 } | |
1189 | |
1190 | |
1097 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1191 Representation StoreIndexedInstr::RequiredInputRepresentation( |
1098 intptr_t idx) const { | 1192 intptr_t idx) const { |
1099 if (idx == 0) return kNoRepresentation; | 1193 if (idx == 0) return kNoRepresentation; |
1100 if (idx == 1) return kTagged; | 1194 if (idx == 1) return kTagged; |
1101 ASSERT(idx == 2); | 1195 ASSERT(idx == 2); |
1102 switch (class_id_) { | 1196 switch (class_id_) { |
1103 case kArrayCid: | 1197 case kArrayCid: |
1104 case kOneByteStringCid: | 1198 case kOneByteStringCid: |
1105 case kTypedDataInt8ArrayCid: | 1199 case kTypedDataInt8ArrayCid: |
1106 case kTypedDataUint8ArrayCid: | 1200 case kTypedDataUint8ArrayCid: |
(...skipping 3358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4465 __ ReserveAlignedFrameSpace(0); | 4559 __ ReserveAlignedFrameSpace(0); |
4466 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 4560 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
4467 __ CallRuntime(TargetFunction(), InputCount()); | 4561 __ CallRuntime(TargetFunction(), InputCount()); |
4468 __ movaps(locs()->out(0).fpu_reg(), XMM0); | 4562 __ movaps(locs()->out(0).fpu_reg(), XMM0); |
4469 // Restore RSP. | 4563 // Restore RSP. |
4470 __ movq(RSP, locs()->temp(0).reg()); | 4564 __ movq(RSP, locs()->temp(0).reg()); |
4471 } | 4565 } |
4472 } | 4566 } |
4473 | 4567 |
4474 | 4568 |
4569 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( | |
4570 Isolate* isolate, bool opt) const { | |
4571 const intptr_t kNumTemps = 1; | |
4572 LocationSummary* summary = new(isolate) LocationSummary( | |
4573 isolate, InputCount(), kNumTemps, LocationSummary::kCall); | |
4574 summary->set_in(0, Location::RegisterLocation(CallingConventions::kArg1Reg)); | |
4575 summary->set_in(1, Location::RegisterLocation(CallingConventions::kArg2Reg)); | |
4576 summary->set_in(2, Location::RegisterLocation(CallingConventions::kArg3Reg)); | |
4577 summary->set_in(3, Location::RegisterLocation(CallingConventions::kArg4Reg)); | |
4578 // R13 is chosen because it is callee saved so we do not need to back it | |
4579 // up before calling into the runtime. | |
4580 summary->set_temp(0, Location::RegisterLocation(R13)); | |
4581 summary->set_out(0, Location::RegisterLocation(RAX)); | |
4582 return summary; | |
4583 } | |
4584 | |
4585 | |
4586 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( | |
4587 FlowGraphCompiler* compiler) { | |
4588 | |
4589 // Save RSP. | |
4590 __ movq(locs()->temp(0).reg(), RSP); | |
4591 __ ReserveAlignedFrameSpace(0); | |
4592 | |
4593 // Call the function. Parameters are already in their correct spots. | |
4594 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); | |
4595 | |
4596 // Restore RSP. | |
4597 __ movq(RSP, locs()->temp(0).reg()); | |
4598 } | |
4599 | |
4600 | |
4475 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 4601 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, |
4476 bool opt) const { | 4602 bool opt) const { |
4477 const intptr_t kNumInputs = 1; | 4603 const intptr_t kNumInputs = 1; |
4478 return LocationSummary::Make(isolate, | 4604 return LocationSummary::Make(isolate, |
4479 kNumInputs, | 4605 kNumInputs, |
4480 Location::SameAsFirstInput(), | 4606 Location::SameAsFirstInput(), |
4481 LocationSummary::kNoCall); | 4607 LocationSummary::kNoCall); |
4482 } | 4608 } |
4483 | 4609 |
4484 | 4610 |
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5686 } | 5812 } |
5687 | 5813 |
5688 | 5814 |
5689 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5815 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5690 if (!compiler->CanFallThroughTo(normal_entry())) { | 5816 if (!compiler->CanFallThroughTo(normal_entry())) { |
5691 __ jmp(compiler->GetJumpLabel(normal_entry())); | 5817 __ jmp(compiler->GetJumpLabel(normal_entry())); |
5692 } | 5818 } |
5693 } | 5819 } |
5694 | 5820 |
5695 | 5821 |
5822 void IndirectEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5823 __ Bind(compiler->GetJumpLabel(this)); | |
5824 if (!compiler->is_optimizing()) { | |
5825 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, | |
5826 deopt_id_, | |
5827 Scanner::kNoSourcePos); | |
5828 } | |
5829 if (HasParallelMove()) { | |
5830 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | |
5831 } | |
5832 } | |
5833 | |
5834 | |
5696 LocationSummary* GotoInstr::MakeLocationSummary(Isolate* isolate, | 5835 LocationSummary* GotoInstr::MakeLocationSummary(Isolate* isolate, |
5697 bool opt) const { | 5836 bool opt) const { |
5698 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kNoCall); | 5837 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kNoCall); |
5699 } | 5838 } |
5700 | 5839 |
5701 | 5840 |
5702 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5841 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5703 if (!compiler->is_optimizing()) { | 5842 if (!compiler->is_optimizing()) { |
5704 if (FLAG_emit_edge_counters) { | 5843 if (FLAG_emit_edge_counters) { |
5705 compiler->EmitEdgeCounter(); | 5844 compiler->EmitEdgeCounter(); |
(...skipping 12 matching lines...) Expand all Loading... | |
5718 } | 5857 } |
5719 | 5858 |
5720 // We can fall through if the successor is the next block in the list. | 5859 // We can fall through if the successor is the next block in the list. |
5721 // Otherwise, we need a jump. | 5860 // Otherwise, we need a jump. |
5722 if (!compiler->CanFallThroughTo(successor())) { | 5861 if (!compiler->CanFallThroughTo(successor())) { |
5723 __ jmp(compiler->GetJumpLabel(successor())); | 5862 __ jmp(compiler->GetJumpLabel(successor())); |
5724 } | 5863 } |
5725 } | 5864 } |
5726 | 5865 |
5727 | 5866 |
5867 | |
5868 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, | |
5869 bool opt) const { | |
5870 const intptr_t kNumInputs = 1; | |
5871 const intptr_t kNumTemps = 1; | |
5872 | |
5873 LocationSummary* locs = new(isolate) LocationSummary( | |
5874 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
5875 | |
5876 locs->set_in(0, Location::RequiresRegister()); | |
5877 locs->set_temp(0, Location::RequiresRegister()); | |
5878 | |
5879 return locs; | |
5880 } | |
5881 | |
5882 | |
5883 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5884 Register sum_reg = locs()->temp_slot(0)->reg(); | |
5885 | |
5886 // Load from [current frame pointer] + kPcMarkerSlotFromFp. | |
5887 __ movq(sum_reg, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); | |
5888 | |
5889 // Subtract the entrypoint offset. | |
5890 __ SubImmediate(sum_reg, | |
Florian Schneider
2014/10/01 17:04:14
Same as on ia32. Try fold it into the addq below.
| |
5891 Immediate(Assembler::EntryPointToPcMarkerOffset()), | |
5892 PP); | |
5893 | |
5894 // Add the offset. | |
5895 Register offset_reg = locs()->in(0).reg(); | |
5896 __ SmiUntag(offset_reg); | |
5897 __ addq(sum_reg, offset_reg); | |
5898 | |
5899 // Jump to the absolute address. | |
5900 __ jmp(sum_reg); | |
5901 } | |
5902 | |
5728 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, | 5903 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, |
5729 bool opt) const { | 5904 bool opt) const { |
5730 return LocationSummary::Make(isolate, | 5905 return LocationSummary::Make(isolate, |
5731 0, | 5906 0, |
5732 Location::RequiresRegister(), | 5907 Location::RequiresRegister(), |
5733 LocationSummary::kNoCall); | 5908 LocationSummary::kNoCall); |
5734 } | 5909 } |
5735 | 5910 |
5736 | 5911 |
5737 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5912 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5922 __ movq(R10, Immediate(kInvalidObjectPointer)); | 6097 __ movq(R10, Immediate(kInvalidObjectPointer)); |
5923 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 6098 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
5924 #endif | 6099 #endif |
5925 } | 6100 } |
5926 | 6101 |
5927 } // namespace dart | 6102 } // namespace dart |
5928 | 6103 |
5929 #undef __ | 6104 #undef __ |
5930 | 6105 |
5931 #endif // defined TARGET_ARCH_X64 | 6106 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |