| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 kNumTemps, | 161 kNumTemps, |
| 162 LocationSummary::kCall); | 162 LocationSummary::kCall); |
| 163 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. | 163 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. |
| 164 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. | 164 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. |
| 165 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. | 165 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. |
| 166 summary->set_out(Location::RegisterLocation(EAX)); | 166 summary->set_out(Location::RegisterLocation(EAX)); |
| 167 return summary; | 167 return summary; |
| 168 } | 168 } |
| 169 | 169 |
| 170 | 170 |
| 171 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
| 172 const intptr_t kNumInputs = 1; |
| 173 const intptr_t kNumTemps = 0; |
| 174 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 175 kNumTemps, |
| 176 LocationSummary::kCall); |
| 177 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 178 locs->set_out(Location::RegisterLocation(EAX)); |
| 179 return locs; |
| 180 } |
| 181 |
| 182 |
| 171 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 183 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 172 Register obj = locs()->in(0).reg(); | 184 Register obj = locs()->in(0).reg(); |
| 173 Register result = locs()->out().reg(); | 185 Register result = locs()->out().reg(); |
| 174 | 186 |
| 175 // Check that the type of the value is allowed in conditional context. | 187 // Check that the type of the value is allowed in conditional context. |
| 176 // Call the runtime if the object is not bool::true or bool::false. | 188 // Call the runtime if the object is not bool::true or bool::false. |
| 177 Label done; | 189 Label done; |
| 178 __ CompareObject(obj, compiler->bool_true()); | 190 __ CompareObject(obj, compiler->bool_true()); |
| 179 __ j(EQUAL, &done, Assembler::kNearJump); | 191 __ j(EQUAL, &done, Assembler::kNearJump); |
| 180 __ CompareObject(obj, compiler->bool_false()); | 192 __ CompareObject(obj, compiler->bool_false()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 locs->set_in(1, Location::RequiresRegister()); | 232 locs->set_in(1, Location::RequiresRegister()); |
| 221 locs->set_temp(0, Location::RequiresRegister()); | 233 locs->set_temp(0, Location::RequiresRegister()); |
| 222 locs->set_out(Location::RequiresRegister()); | 234 locs->set_out(Location::RequiresRegister()); |
| 223 return locs; | 235 return locs; |
| 224 } | 236 } |
| 225 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 237 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 226 const intptr_t kNumTemps = 1; | 238 const intptr_t kNumTemps = 1; |
| 227 LocationSummary* locs = new LocationSummary(kNumInputs, | 239 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 228 kNumTemps, | 240 kNumTemps, |
| 229 LocationSummary::kCall); | 241 LocationSummary::kCall); |
| 230 locs->set_in(0, Location::RequiresRegister()); | 242 locs->set_in(0, Location::RegisterLocation(ECX)); |
| 231 locs->set_in(1, Location::RequiresRegister()); | 243 locs->set_in(1, Location::RegisterLocation(EDX)); |
| 232 locs->set_temp(0, Location::RequiresRegister()); | 244 locs->set_temp(0, Location::RegisterLocation(EBX)); |
| 233 locs->set_out(Location::RegisterLocation(EAX)); | 245 locs->set_out(Location::RegisterLocation(EAX)); |
| 234 return locs; | 246 return locs; |
| 235 } | 247 } |
| 236 const intptr_t kNumTemps = 0; | 248 const intptr_t kNumTemps = 0; |
| 237 LocationSummary* locs = new LocationSummary(kNumInputs, | 249 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 238 kNumTemps, | 250 kNumTemps, |
| 239 LocationSummary::kCall); | 251 LocationSummary::kCall); |
| 240 locs->set_in(0, Location::RequiresRegister()); | 252 locs->set_in(0, Location::RegisterLocation(ECX)); |
| 241 locs->set_in(1, Location::RequiresRegister()); | 253 locs->set_in(1, Location::RegisterLocation(EDX)); |
| 242 locs->set_out(Location::RegisterLocation(EAX)); | 254 locs->set_out(Location::RegisterLocation(EAX)); |
| 243 return locs; | 255 return locs; |
| 244 } | 256 } |
| 245 | 257 |
| 246 | 258 |
| 247 // Optional integer arguments can often be null. Null is not collected | 259 // Optional integer arguments can often be null. Null is not collected |
| 248 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? | 260 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? |
| 249 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, | 261 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, |
| 250 EqualityCompareComp* comp) { | 262 EqualityCompareComp* comp) { |
| 251 Register left = comp->locs()->in(0).reg(); | 263 Register left = comp->locs()->in(0).reg(); |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); | 1137 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); |
| 1126 for (int i = ElementCount() - 1; i >= 0; --i) { | 1138 for (int i = ElementCount() - 1; i >= 0; --i) { |
| 1127 ASSERT(ElementAt(i)->IsUse()); | 1139 ASSERT(ElementAt(i)->IsUse()); |
| 1128 __ popl(Address(temp_reg, i * kWordSize)); | 1140 __ popl(Address(temp_reg, i * kWordSize)); |
| 1129 } | 1141 } |
| 1130 } | 1142 } |
| 1131 | 1143 |
| 1132 | 1144 |
| 1133 LocationSummary* | 1145 LocationSummary* |
| 1134 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { | 1146 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { |
| 1135 return LocationSummary::Make(2, | 1147 const intptr_t kNumInputs = 2; |
| 1136 Location::RequiresRegister(), | 1148 const intptr_t kNumTemps = 0; |
| 1137 LocationSummary::kCall); | 1149 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 1150 kNumTemps, |
| 1151 LocationSummary::kCall); |
| 1152 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 1153 locs->set_in(1, Location::RegisterLocation(ECX)); |
| 1154 locs->set_out(Location::RegisterLocation(EAX)); |
| 1155 return locs; |
| 1138 } | 1156 } |
| 1139 | 1157 |
| 1140 | 1158 |
| 1141 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 1159 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
| 1142 FlowGraphCompiler* compiler) { | 1160 FlowGraphCompiler* compiler) { |
| 1143 const Class& cls = Class::ZoneHandle(constructor().owner()); | 1161 const Class& cls = Class::ZoneHandle(constructor().owner()); |
| 1144 Register type_arguments = locs()->in(0).reg(); | 1162 Register type_arguments = locs()->in(0).reg(); |
| 1145 Register instantiator_type_arguments = locs()->in(1).reg(); | 1163 Register instantiator_type_arguments = locs()->in(1).reg(); |
| 1146 Register result = locs()->out().reg(); | 1164 Register result = locs()->out().reg(); |
| 1147 | 1165 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1204 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
| 1187 } | 1205 } |
| 1188 | 1206 |
| 1189 | 1207 |
| 1190 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 1208 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
| 1191 const intptr_t kNumInputs = 1; | 1209 const intptr_t kNumInputs = 1; |
| 1192 const intptr_t kNumTemps = 1; | 1210 const intptr_t kNumTemps = 1; |
| 1193 LocationSummary* locs = new LocationSummary(kNumInputs, | 1211 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 1194 kNumTemps, | 1212 kNumTemps, |
| 1195 LocationSummary::kCall); | 1213 LocationSummary::kCall); |
| 1196 locs->set_in(0, Location::RequiresRegister()); | 1214 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 1197 locs->set_temp(0, Location::RequiresRegister()); | 1215 locs->set_temp(0, Location::RegisterLocation(ECX)); |
| 1198 locs->set_out(Location::SameAsFirstInput()); | 1216 locs->set_out(Location::RegisterLocation(EAX)); |
| 1199 return locs; | 1217 return locs; |
| 1200 } | 1218 } |
| 1201 | 1219 |
| 1202 | 1220 |
| 1203 void InstantiateTypeArgumentsComp::EmitNativeCode( | 1221 void InstantiateTypeArgumentsComp::EmitNativeCode( |
| 1204 FlowGraphCompiler* compiler) { | 1222 FlowGraphCompiler* compiler) { |
| 1205 Register instantiator_reg = locs()->in(0).reg(); | 1223 Register instantiator_reg = locs()->in(0).reg(); |
| 1206 Register temp = locs()->temp(0).reg(); | 1224 Register temp = locs()->temp(0).reg(); |
| 1207 Register result_reg = locs()->out().reg(); | 1225 Register result_reg = locs()->out().reg(); |
| 1208 | 1226 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1478 if (operands_type() == kDoubleOperands) { | 1496 if (operands_type() == kDoubleOperands) { |
| 1479 return MakeCallSummary(); // Calls into a stub for allocation. | 1497 return MakeCallSummary(); // Calls into a stub for allocation. |
| 1480 } | 1498 } |
| 1481 | 1499 |
| 1482 if (operands_type() == kMintOperands) { | 1500 if (operands_type() == kMintOperands) { |
| 1483 ASSERT(op_kind() == Token::kBIT_AND); | 1501 ASSERT(op_kind() == Token::kBIT_AND); |
| 1484 const intptr_t kNumTemps = 1; | 1502 const intptr_t kNumTemps = 1; |
| 1485 LocationSummary* summary = | 1503 LocationSummary* summary = |
| 1486 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1504 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1487 summary->set_in(0, Location::RegisterLocation(EAX)); | 1505 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1488 summary->set_in(1, Location::RequiresRegister()); | 1506 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1489 summary->set_out(Location::SameAsFirstInput()); | 1507 summary->set_temp(0, Location::RegisterLocation(EDX)); |
| 1490 summary->set_temp(0, Location::RequiresRegister()); | 1508 summary->set_out(Location::RegisterLocation(EAX)); |
| 1491 return summary; | 1509 return summary; |
| 1492 } | 1510 } |
| 1493 | 1511 |
| 1494 ASSERT(operands_type() == kSmiOperands); | 1512 ASSERT(operands_type() == kSmiOperands); |
| 1495 | 1513 |
| 1496 if (op_kind() == Token::kTRUNCDIV) { | 1514 if (op_kind() == Token::kTRUNCDIV) { |
| 1497 const intptr_t kNumTemps = 3; | 1515 const intptr_t kNumTemps = 3; |
| 1498 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1516 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1499 summary->set_in(0, Location::RegisterLocation(EAX)); | 1517 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1500 summary->set_in(1, Location::RegisterLocation(ECX)); | 1518 summary->set_in(1, Location::RegisterLocation(ECX)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1511 summary->set_in(1, Location::RegisterLocation(ECX)); | 1529 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 1512 summary->set_out(Location::SameAsFirstInput()); | 1530 summary->set_out(Location::SameAsFirstInput()); |
| 1513 summary->set_temp(0, Location::RequiresRegister()); | 1531 summary->set_temp(0, Location::RequiresRegister()); |
| 1514 return summary; | 1532 return summary; |
| 1515 } else if (op_kind() == Token::kSHL) { | 1533 } else if (op_kind() == Token::kSHL) { |
| 1516 // Two Smi operands can easily overflow into Mint. | 1534 // Two Smi operands can easily overflow into Mint. |
| 1517 const intptr_t kNumTemps = 2; | 1535 const intptr_t kNumTemps = 2; |
| 1518 LocationSummary* summary = | 1536 LocationSummary* summary = |
| 1519 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1520 summary->set_in(0, Location::RegisterLocation(EAX)); | 1538 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1521 summary->set_in(1, Location::RequiresRegister()); | 1539 summary->set_in(1, Location::RegisterLocation(EDX)); |
| 1522 summary->set_out(Location::SameAsFirstInput()); | 1540 summary->set_temp(0, Location::RegisterLocation(EBX)); |
| 1523 summary->set_temp(0, Location::RequiresRegister()); | |
| 1524 summary->set_temp(1, Location::RegisterLocation(ECX)); | 1541 summary->set_temp(1, Location::RegisterLocation(ECX)); |
| 1542 summary->set_out(Location::RegisterLocation(EAX)); |
| 1525 return summary; | 1543 return summary; |
| 1526 } else { | 1544 } else { |
| 1527 const intptr_t kNumTemps = 1; | 1545 const intptr_t kNumTemps = 1; |
| 1528 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1546 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1529 summary->set_in(0, Location::RequiresRegister()); | 1547 summary->set_in(0, Location::RequiresRegister()); |
| 1530 summary->set_in(1, Location::RequiresRegister()); | 1548 summary->set_in(1, Location::RequiresRegister()); |
| 1531 summary->set_out(Location::SameAsFirstInput()); | 1549 summary->set_out(Location::SameAsFirstInput()); |
| 1532 summary->set_temp(0, Location::RequiresRegister()); | 1550 summary->set_temp(0, Location::RequiresRegister()); |
| 1533 return summary; | 1551 return summary; |
| 1534 } | 1552 } |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1890 } | 1908 } |
| 1891 } | 1909 } |
| 1892 | 1910 |
| 1893 | 1911 |
| 1894 LocationSummary* NumberNegateComp::MakeLocationSummary() const { | 1912 LocationSummary* NumberNegateComp::MakeLocationSummary() const { |
| 1895 const intptr_t kNumInputs = 1; | 1913 const intptr_t kNumInputs = 1; |
| 1896 const intptr_t kNumTemps = 1; // Needed for doubles. | 1914 const intptr_t kNumTemps = 1; // Needed for doubles. |
| 1897 LocationSummary* summary = new LocationSummary(kNumInputs, | 1915 LocationSummary* summary = new LocationSummary(kNumInputs, |
| 1898 kNumTemps, | 1916 kNumTemps, |
| 1899 LocationSummary::kCall); | 1917 LocationSummary::kCall); |
| 1900 summary->set_in(0, Location::RequiresRegister()); | 1918 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 1901 summary->set_out(Location::SameAsFirstInput()); | 1919 summary->set_temp(0, Location::RegisterLocation(ECX)); |
| 1902 summary->set_temp(0, Location::RequiresRegister()); | 1920 summary->set_out(Location::RegisterLocation(EAX)); |
| 1903 return summary; | 1921 return summary; |
| 1904 } | 1922 } |
| 1905 | 1923 |
| 1906 | 1924 |
| 1907 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1925 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1908 const ICData& ic_data = *instance_call()->ic_data(); | 1926 const ICData& ic_data = *instance_call()->ic_data(); |
| 1909 ASSERT(!ic_data.IsNull()); | 1927 ASSERT(!ic_data.IsNull()); |
| 1910 ASSERT(ic_data.num_args_tested() == 1); | 1928 ASSERT(ic_data.num_args_tested() == 1); |
| 1911 | 1929 |
| 1912 // TODO(srdjan): Implement for more checks. | 1930 // TODO(srdjan): Implement for more checks. |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2100 summary->set_in(1, Location::RequiresRegister()); | 2118 summary->set_in(1, Location::RequiresRegister()); |
| 2101 summary->set_temp(0, Location::RequiresRegister()); | 2119 summary->set_temp(0, Location::RequiresRegister()); |
| 2102 return summary; | 2120 return summary; |
| 2103 } | 2121 } |
| 2104 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { | 2122 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { |
| 2105 const intptr_t kNumInputs = 2; | 2123 const intptr_t kNumInputs = 2; |
| 2106 const intptr_t kNumTemps = 1; | 2124 const intptr_t kNumTemps = 1; |
| 2107 LocationSummary* locs = new LocationSummary(kNumInputs, | 2125 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 2108 kNumTemps, | 2126 kNumTemps, |
| 2109 LocationSummary::kCall); | 2127 LocationSummary::kCall); |
| 2110 locs->set_in(0, Location::RequiresRegister()); | 2128 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 2111 locs->set_in(1, Location::RequiresRegister()); | 2129 locs->set_in(1, Location::RegisterLocation(ECX)); |
| 2112 locs->set_temp(0, Location::RequiresRegister()); | 2130 locs->set_temp(0, Location::RegisterLocation(EDX)); |
| 2113 return locs; | 2131 return locs; |
| 2114 } | 2132 } |
| 2115 // Otherwise polymorphic dispatch. | 2133 // Otherwise polymorphic dispatch. |
| 2116 } | 2134 } |
| 2117 // Call. | 2135 // Call. |
| 2118 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 2136 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| 2119 result->set_out(Location::RegisterLocation(EAX)); | 2137 result->set_out(Location::RegisterLocation(EAX)); |
| 2120 return result; | 2138 return result; |
| 2121 } | 2139 } |
| 2122 | 2140 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2171 ASSERT(locs()->out().reg() == EAX); | 2189 ASSERT(locs()->out().reg() == EAX); |
| 2172 __ CompareObject(locs()->out().reg(), compiler->bool_true()); | 2190 __ CompareObject(locs()->out().reg(), compiler->bool_true()); |
| 2173 EmitBranchOnCondition(compiler, branch_condition); | 2191 EmitBranchOnCondition(compiler, branch_condition); |
| 2174 } | 2192 } |
| 2175 | 2193 |
| 2176 } // namespace dart | 2194 } // namespace dart |
| 2177 | 2195 |
| 2178 #undef __ | 2196 #undef __ |
| 2179 | 2197 |
| 2180 #endif // defined TARGET_ARCH_X64 | 2198 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |