| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 kNumTemps, | 169 kNumTemps, |
| 170 LocationSummary::kCall); | 170 LocationSummary::kCall); |
| 171 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. | 171 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. |
| 172 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. | 172 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. |
| 173 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. | 173 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. |
| 174 summary->set_out(Location::RegisterLocation(RAX)); | 174 summary->set_out(Location::RegisterLocation(RAX)); |
| 175 return summary; | 175 return summary; |
| 176 } | 176 } |
| 177 | 177 |
| 178 | 178 |
| 179 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
| 180 const intptr_t kNumInputs = 1; |
| 181 const intptr_t kNumTemps = 0; |
| 182 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 183 kNumTemps, |
| 184 LocationSummary::kCall); |
| 185 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 186 locs->set_out(Location::RegisterLocation(RAX)); |
| 187 return locs; |
| 188 } |
| 189 |
| 190 |
| 179 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 191 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 180 Register obj = locs()->in(0).reg(); | 192 Register obj = locs()->in(0).reg(); |
| 181 Register result = locs()->out().reg(); | 193 Register result = locs()->out().reg(); |
| 182 | 194 |
| 183 // Check that the type of the value is allowed in conditional context. | 195 // Check that the type of the value is allowed in conditional context. |
| 184 // Call the runtime if the object is not bool::true or bool::false. | 196 // Call the runtime if the object is not bool::true or bool::false. |
| 185 Label done; | 197 Label done; |
| 186 __ CompareObject(obj, compiler->bool_true()); | 198 __ CompareObject(obj, compiler->bool_true()); |
| 187 __ j(EQUAL, &done, Assembler::kNearJump); | 199 __ j(EQUAL, &done, Assembler::kNearJump); |
| 188 __ CompareObject(obj, compiler->bool_false()); | 200 __ CompareObject(obj, compiler->bool_false()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 locs->set_temp(0, Location::RequiresRegister()); | 243 locs->set_temp(0, Location::RequiresRegister()); |
| 232 } | 244 } |
| 233 locs->set_out(Location::RequiresRegister()); | 245 locs->set_out(Location::RequiresRegister()); |
| 234 return locs; | 246 return locs; |
| 235 } | 247 } |
| 236 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 248 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 237 const intptr_t kNumTemps = 1; | 249 const intptr_t kNumTemps = 1; |
| 238 LocationSummary* locs = new LocationSummary(kNumInputs, | 250 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 239 kNumTemps, | 251 kNumTemps, |
| 240 LocationSummary::kCall); | 252 LocationSummary::kCall); |
| 241 locs->set_in(0, Location::RequiresRegister()); | 253 locs->set_in(0, Location::RegisterLocation(RCX)); |
| 242 locs->set_in(1, Location::RequiresRegister()); | 254 locs->set_in(1, Location::RegisterLocation(RDX)); |
| 243 locs->set_temp(0, Location::RequiresRegister()); | 255 locs->set_temp(0, Location::RegisterLocation(RBX)); |
| 244 locs->set_out(Location::RegisterLocation(RAX)); | 256 locs->set_out(Location::RegisterLocation(RAX)); |
| 245 return locs; | 257 return locs; |
| 246 } | 258 } |
| 247 const intptr_t kNumTemps = 0; | 259 const intptr_t kNumTemps = 0; |
| 248 LocationSummary* locs = new LocationSummary(kNumInputs, | 260 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 249 kNumTemps, | 261 kNumTemps, |
| 250 LocationSummary::kCall); | 262 LocationSummary::kCall); |
| 251 locs->set_in(0, Location::RequiresRegister()); | 263 locs->set_in(0, Location::RegisterLocation(RCX)); |
| 252 locs->set_in(1, Location::RequiresRegister()); | 264 locs->set_in(1, Location::RegisterLocation(RDX)); |
| 253 locs->set_out(Location::RegisterLocation(RAX)); | 265 locs->set_out(Location::RegisterLocation(RAX)); |
| 254 return locs; | 266 return locs; |
| 255 } | 267 } |
| 256 | 268 |
| 257 | 269 |
| 258 // Optional integer arguments can often be null. Null is not collected | 270 // Optional integer arguments can often be null. Null is not collected |
| 259 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? | 271 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? |
| 260 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, | 272 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, |
| 261 EqualityCompareComp* comp) { | 273 EqualityCompareComp* comp) { |
| 262 Register left = comp->locs()->in(0).reg(); | 274 Register left = comp->locs()->in(0).reg(); |
| (...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1134 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); | 1146 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); |
| 1135 for (int i = ElementCount() - 1; i >= 0; --i) { | 1147 for (int i = ElementCount() - 1; i >= 0; --i) { |
| 1136 ASSERT(ElementAt(i)->IsUse()); | 1148 ASSERT(ElementAt(i)->IsUse()); |
| 1137 __ popq(Address(temp_reg, i * kWordSize)); | 1149 __ popq(Address(temp_reg, i * kWordSize)); |
| 1138 } | 1150 } |
| 1139 } | 1151 } |
| 1140 | 1152 |
| 1141 | 1153 |
| 1142 LocationSummary* | 1154 LocationSummary* |
| 1143 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { | 1155 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { |
| 1144 return LocationSummary::Make(2, | 1156 const intptr_t kNumInputs = 2; |
| 1145 Location::RequiresRegister(), | 1157 const intptr_t kNumTemps = 0; |
| 1146 LocationSummary::kCall); | 1158 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 1159 kNumTemps, |
| 1160 LocationSummary::kCall); |
| 1161 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 1162 locs->set_in(1, Location::RegisterLocation(RCX)); |
| 1163 locs->set_out(Location::RegisterLocation(RAX)); |
| 1164 return locs; |
| 1147 } | 1165 } |
| 1148 | 1166 |
| 1149 | 1167 |
| 1150 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 1168 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
| 1151 FlowGraphCompiler* compiler) { | 1169 FlowGraphCompiler* compiler) { |
| 1152 const Class& cls = Class::ZoneHandle(constructor().owner()); | 1170 const Class& cls = Class::ZoneHandle(constructor().owner()); |
| 1153 Register type_arguments = locs()->in(0).reg(); | 1171 Register type_arguments = locs()->in(0).reg(); |
| 1154 Register instantiator_type_arguments = locs()->in(1).reg(); | 1172 Register instantiator_type_arguments = locs()->in(1).reg(); |
| 1155 Register result = locs()->out().reg(); | 1173 Register result = locs()->out().reg(); |
| 1156 | 1174 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1212 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
| 1195 } | 1213 } |
| 1196 | 1214 |
| 1197 | 1215 |
| 1198 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 1216 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
| 1199 const intptr_t kNumInputs = 1; | 1217 const intptr_t kNumInputs = 1; |
| 1200 const intptr_t kNumTemps = 0; | 1218 const intptr_t kNumTemps = 0; |
| 1201 LocationSummary* locs = new LocationSummary(kNumInputs, | 1219 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 1202 kNumTemps, | 1220 kNumTemps, |
| 1203 LocationSummary::kCall); | 1221 LocationSummary::kCall); |
| 1204 locs->set_in(0, Location::RequiresRegister()); | 1222 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 1205 locs->set_out(Location::SameAsFirstInput()); | 1223 locs->set_out(Location::RegisterLocation(RAX)); |
| 1206 return locs; | 1224 return locs; |
| 1207 } | 1225 } |
| 1208 | 1226 |
| 1209 | 1227 |
| 1210 void InstantiateTypeArgumentsComp::EmitNativeCode( | 1228 void InstantiateTypeArgumentsComp::EmitNativeCode( |
| 1211 FlowGraphCompiler* compiler) { | 1229 FlowGraphCompiler* compiler) { |
| 1212 Register instantiator_reg = locs()->in(0).reg(); | 1230 Register instantiator_reg = locs()->in(0).reg(); |
| 1213 Register result_reg = locs()->out().reg(); | 1231 Register result_reg = locs()->out().reg(); |
| 1214 | 1232 |
| 1215 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 1233 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1489 if (operands_type() == kDoubleOperands) { | 1507 if (operands_type() == kDoubleOperands) { |
| 1490 return MakeCallSummary(); // Calls into a stub for allocation. | 1508 return MakeCallSummary(); // Calls into a stub for allocation. |
| 1491 } | 1509 } |
| 1492 | 1510 |
| 1493 if (operands_type() == kMintOperands) { | 1511 if (operands_type() == kMintOperands) { |
| 1494 ASSERT(op_kind() == Token::kBIT_AND); | 1512 ASSERT(op_kind() == Token::kBIT_AND); |
| 1495 const intptr_t kNumTemps = 0; | 1513 const intptr_t kNumTemps = 0; |
| 1496 LocationSummary* summary = | 1514 LocationSummary* summary = |
| 1497 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1515 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1498 summary->set_in(0, Location::RegisterLocation(RAX)); | 1516 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1499 summary->set_in(1, Location::RequiresRegister()); | 1517 summary->set_in(1, Location::RegisterLocation(RCX)); |
| 1500 summary->set_out(Location::SameAsFirstInput()); | 1518 summary->set_out(Location::RegisterLocation(RAX)); |
| 1501 return summary; | 1519 return summary; |
| 1502 } | 1520 } |
| 1503 | 1521 |
| 1504 ASSERT(operands_type() == kSmiOperands); | 1522 ASSERT(operands_type() == kSmiOperands); |
| 1505 | 1523 |
| 1506 if (op_kind() == Token::kTRUNCDIV) { | 1524 if (op_kind() == Token::kTRUNCDIV) { |
| 1507 const intptr_t kNumTemps = 3; | 1525 const intptr_t kNumTemps = 3; |
| 1508 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1526 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1509 summary->set_in(0, Location::RegisterLocation(RAX)); | 1527 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1510 summary->set_in(1, Location::RegisterLocation(RCX)); | 1528 summary->set_in(1, Location::RegisterLocation(RCX)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1521 summary->set_in(1, Location::RegisterLocation(RCX)); | 1539 summary->set_in(1, Location::RegisterLocation(RCX)); |
| 1522 summary->set_out(Location::SameAsFirstInput()); | 1540 summary->set_out(Location::SameAsFirstInput()); |
| 1523 summary->set_temp(0, Location::RequiresRegister()); | 1541 summary->set_temp(0, Location::RequiresRegister()); |
| 1524 return summary; | 1542 return summary; |
| 1525 } else if (op_kind() == Token::kSHL) { | 1543 } else if (op_kind() == Token::kSHL) { |
| 1526 // Two Smi operands can easily overflow into Mint. | 1544 // Two Smi operands can easily overflow into Mint. |
| 1527 const intptr_t kNumTemps = 2; | 1545 const intptr_t kNumTemps = 2; |
| 1528 LocationSummary* summary = | 1546 LocationSummary* summary = |
| 1529 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1530 summary->set_in(0, Location::RegisterLocation(RAX)); | 1548 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1531 summary->set_in(1, Location::RequiresRegister()); | 1549 summary->set_in(1, Location::RegisterLocation(RDX)); |
| 1532 summary->set_out(Location::SameAsFirstInput()); | 1550 summary->set_out(Location::RegisterLocation(RAX)); |
| 1533 summary->set_temp(0, Location::RequiresRegister()); | 1551 summary->set_temp(0, Location::RegisterLocation(RBX)); |
| 1534 summary->set_temp(1, Location::RegisterLocation(RCX)); | 1552 summary->set_temp(1, Location::RegisterLocation(RCX)); |
| 1535 return summary; | 1553 return summary; |
| 1536 } else { | 1554 } else { |
| 1537 const intptr_t kNumTemps = 1; | 1555 const intptr_t kNumTemps = 1; |
| 1538 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1556 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1539 summary->set_in(0, Location::RequiresRegister()); | 1557 summary->set_in(0, Location::RequiresRegister()); |
| 1540 summary->set_in(1, Location::RequiresRegister()); | 1558 summary->set_in(1, Location::RequiresRegister()); |
| 1541 summary->set_out(Location::SameAsFirstInput()); | 1559 summary->set_out(Location::SameAsFirstInput()); |
| 1542 summary->set_temp(0, Location::RequiresRegister()); | 1560 summary->set_temp(0, Location::RequiresRegister()); |
| 1543 return summary; | 1561 return summary; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1899 } | 1917 } |
| 1900 } | 1918 } |
| 1901 | 1919 |
| 1902 | 1920 |
| 1903 LocationSummary* NumberNegateComp::MakeLocationSummary() const { | 1921 LocationSummary* NumberNegateComp::MakeLocationSummary() const { |
| 1904 const intptr_t kNumInputs = 1; | 1922 const intptr_t kNumInputs = 1; |
| 1905 const intptr_t kNumTemps = 1; // Needed for doubles. | 1923 const intptr_t kNumTemps = 1; // Needed for doubles. |
| 1906 LocationSummary* summary = new LocationSummary(kNumInputs, | 1924 LocationSummary* summary = new LocationSummary(kNumInputs, |
| 1907 kNumTemps, | 1925 kNumTemps, |
| 1908 LocationSummary::kCall); | 1926 LocationSummary::kCall); |
| 1909 summary->set_in(0, Location::RequiresRegister()); | 1927 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1910 summary->set_out(Location::SameAsFirstInput()); | 1928 summary->set_out(Location::RegisterLocation(RAX)); |
| 1911 summary->set_temp(0, Location::RequiresRegister()); | 1929 summary->set_temp(0, Location::RegisterLocation(RCX)); |
| 1912 return summary; | 1930 return summary; |
| 1913 } | 1931 } |
| 1914 | 1932 |
| 1915 | 1933 |
| 1916 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1934 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1917 const ICData& ic_data = *instance_call()->ic_data(); | 1935 const ICData& ic_data = *instance_call()->ic_data(); |
| 1918 ASSERT(!ic_data.IsNull()); | 1936 ASSERT(!ic_data.IsNull()); |
| 1919 ASSERT(ic_data.num_args_tested() == 1); | 1937 ASSERT(ic_data.num_args_tested() == 1); |
| 1920 | 1938 |
| 1921 // TODO(srdjan): Implement for more checks. | 1939 // TODO(srdjan): Implement for more checks. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2106 summary->set_in(1, Location::RequiresRegister()); | 2124 summary->set_in(1, Location::RequiresRegister()); |
| 2107 summary->set_temp(0, Location::RequiresRegister()); | 2125 summary->set_temp(0, Location::RequiresRegister()); |
| 2108 return summary; | 2126 return summary; |
| 2109 } | 2127 } |
| 2110 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { | 2128 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { |
| 2111 const intptr_t kNumInputs = 2; | 2129 const intptr_t kNumInputs = 2; |
| 2112 const intptr_t kNumTemps = 1; | 2130 const intptr_t kNumTemps = 1; |
| 2113 LocationSummary* locs = new LocationSummary(kNumInputs, | 2131 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 2114 kNumTemps, | 2132 kNumTemps, |
| 2115 LocationSummary::kCall); | 2133 LocationSummary::kCall); |
| 2116 locs->set_in(0, Location::RequiresRegister()); | 2134 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 2117 locs->set_in(1, Location::RequiresRegister()); | 2135 locs->set_in(1, Location::RegisterLocation(RCX)); |
| 2118 locs->set_temp(0, Location::RequiresRegister()); | 2136 locs->set_temp(0, Location::RegisterLocation(RDX)); |
| 2119 return locs; | 2137 return locs; |
| 2120 } | 2138 } |
| 2121 // Otherwise polymorphic dispatch. | 2139 // Otherwise polymorphic dispatch. |
| 2122 } | 2140 } |
| 2123 // Call. | 2141 // Call. |
| 2124 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 2142 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| 2125 result->set_out(Location::RegisterLocation(RAX)); | 2143 result->set_out(Location::RegisterLocation(RAX)); |
| 2126 return result; | 2144 return result; |
| 2127 } | 2145 } |
| 2128 | 2146 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2177 ASSERT(locs()->out().reg() == RAX); | 2195 ASSERT(locs()->out().reg() == RAX); |
| 2178 __ CompareObject(locs()->out().reg(), compiler->bool_true()); | 2196 __ CompareObject(locs()->out().reg(), compiler->bool_true()); |
| 2179 EmitBranchOnCondition(compiler, branch_condition); | 2197 EmitBranchOnCondition(compiler, branch_condition); |
| 2180 } | 2198 } |
| 2181 | 2199 |
| 2182 } // namespace dart | 2200 } // namespace dart |
| 2183 | 2201 |
| 2184 #undef __ | 2202 #undef __ |
| 2185 | 2203 |
| 2186 #endif // defined TARGET_ARCH_X64 | 2204 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |