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* locs = new(isolate) LocationSummary( |
| 1116 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1117 locs->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 locs->set_in(1, index_scale() == 1 ? Location::WritableRegister() |
| 1121 : Location::RequiresRegister()); |
| 1122 locs->set_out(0, Location::RequiresRegister()); |
| 1123 return locs; |
| 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 3362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4469 __ ReserveAlignedFrameSpace(0); | 4537 __ ReserveAlignedFrameSpace(0); |
4470 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 4538 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
4471 __ CallRuntime(TargetFunction(), InputCount()); | 4539 __ CallRuntime(TargetFunction(), InputCount()); |
4472 __ movaps(locs()->out(0).fpu_reg(), XMM0); | 4540 __ movaps(locs()->out(0).fpu_reg(), XMM0); |
4473 // Restore RSP. | 4541 // Restore RSP. |
4474 __ movq(RSP, locs()->temp(0).reg()); | 4542 __ movq(RSP, locs()->temp(0).reg()); |
4475 } | 4543 } |
4476 } | 4544 } |
4477 | 4545 |
4478 | 4546 |
| 4547 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( |
| 4548 Isolate* isolate, bool opt) const { |
| 4549 const intptr_t kNumTemps = 0; |
| 4550 LocationSummary* summary = new(isolate) LocationSummary( |
| 4551 isolate, InputCount(), kNumTemps, LocationSummary::kCall); |
| 4552 summary->set_in(0, Location::RegisterLocation(CallingConventions::kArg1Reg)); |
| 4553 summary->set_in(1, Location::RegisterLocation(CallingConventions::kArg2Reg)); |
| 4554 summary->set_in(2, Location::RegisterLocation(CallingConventions::kArg3Reg)); |
| 4555 summary->set_in(3, Location::RegisterLocation(CallingConventions::kArg4Reg)); |
| 4556 summary->set_out(0, Location::RegisterLocation(RAX)); |
| 4557 return summary; |
| 4558 } |
| 4559 |
| 4560 |
| 4561 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( |
| 4562 FlowGraphCompiler* compiler) { |
| 4563 |
| 4564 // Save RSP. R13 is chosen because it is callee saved so we do not need to |
| 4565 // back it up before calling into the runtime. |
| 4566 static const Register kSavedSPReg = R13; |
| 4567 __ movq(kSavedSPReg, RSP); |
| 4568 __ ReserveAlignedFrameSpace(0); |
| 4569 |
| 4570 // Call the function. Parameters are already in their correct spots. |
| 4571 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); |
| 4572 |
| 4573 // Restore RSP. |
| 4574 __ movq(RSP, kSavedSPReg); |
| 4575 } |
| 4576 |
| 4577 |
4479 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 4578 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, |
4480 bool opt) const { | 4579 bool opt) const { |
4481 const intptr_t kNumInputs = 1; | 4580 const intptr_t kNumInputs = 1; |
4482 return LocationSummary::Make(isolate, | 4581 return LocationSummary::Make(isolate, |
4483 kNumInputs, | 4582 kNumInputs, |
4484 Location::SameAsFirstInput(), | 4583 Location::SameAsFirstInput(), |
4485 LocationSummary::kNoCall); | 4584 LocationSummary::kNoCall); |
4486 } | 4585 } |
4487 | 4586 |
4488 | 4587 |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5722 } | 5821 } |
5723 | 5822 |
5724 // We can fall through if the successor is the next block in the list. | 5823 // We can fall through if the successor is the next block in the list. |
5725 // Otherwise, we need a jump. | 5824 // Otherwise, we need a jump. |
5726 if (!compiler->CanFallThroughTo(successor())) { | 5825 if (!compiler->CanFallThroughTo(successor())) { |
5727 __ jmp(compiler->GetJumpLabel(successor())); | 5826 __ jmp(compiler->GetJumpLabel(successor())); |
5728 } | 5827 } |
5729 } | 5828 } |
5730 | 5829 |
5731 | 5830 |
| 5831 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, |
| 5832 bool opt) const { |
| 5833 const intptr_t kNumInputs = 1; |
| 5834 const intptr_t kNumTemps = 1; |
| 5835 |
| 5836 LocationSummary* locs = new(isolate) LocationSummary( |
| 5837 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5838 |
| 5839 locs->set_in(0, Location::RequiresRegister()); |
| 5840 locs->set_temp(0, Location::RequiresRegister()); |
| 5841 |
| 5842 return locs; |
| 5843 } |
| 5844 |
| 5845 |
| 5846 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5847 Register offset_reg = locs()->in(0).reg(); |
| 5848 Register target_address_reg = locs()->temp_slot(0)->reg(); |
| 5849 |
| 5850 // Load from [current frame pointer] + kPcMarkerSlotFromFp. |
| 5851 __ movq(target_address_reg, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); |
| 5852 |
| 5853 // Calculate the final absolute address. |
| 5854 __ SmiUntag(offset_reg); |
| 5855 __ addq(target_address_reg, offset_reg); |
| 5856 |
| 5857 // Jump to the absolute address. |
| 5858 __ jmp(target_address_reg); |
| 5859 } |
| 5860 |
5732 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 5861 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, |
5733 bool opt) const { | 5862 bool opt) const { |
5734 const intptr_t kNumInputs = 2; | 5863 const intptr_t kNumInputs = 2; |
5735 const intptr_t kNumTemps = 0; | 5864 const intptr_t kNumTemps = 0; |
5736 if (needs_number_check()) { | 5865 if (needs_number_check()) { |
5737 LocationSummary* locs = new(isolate) LocationSummary( | 5866 LocationSummary* locs = new(isolate) LocationSummary( |
5738 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 5867 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
5739 locs->set_in(0, Location::RegisterLocation(RAX)); | 5868 locs->set_in(0, Location::RegisterLocation(RAX)); |
5740 locs->set_in(1, Location::RegisterLocation(RCX)); | 5869 locs->set_in(1, Location::RegisterLocation(RCX)); |
5741 locs->set_out(0, Location::RegisterLocation(RAX)); | 5870 locs->set_out(0, Location::RegisterLocation(RAX)); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5913 __ movq(R10, Immediate(kInvalidObjectPointer)); | 6042 __ movq(R10, Immediate(kInvalidObjectPointer)); |
5914 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 6043 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
5915 #endif | 6044 #endif |
5916 } | 6045 } |
5917 | 6046 |
5918 } // namespace dart | 6047 } // namespace dart |
5919 | 6048 |
5920 #undef __ | 6049 #undef __ |
5921 | 6050 |
5922 #endif // defined TARGET_ARCH_X64 | 6051 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |