Chromium Code Reviews| 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 kConditionTypeErrorRuntimeEntry); | 185 kConditionTypeErrorRuntimeEntry); |
| 186 // We should never return here. | 186 // We should never return here. |
| 187 __ int3(); | 187 __ int3(); |
| 188 | 188 |
| 189 __ Bind(&done); | 189 __ Bind(&done); |
| 190 ASSERT(obj == result); | 190 ASSERT(obj == result); |
| 191 } | 191 } |
| 192 | 192 |
| 193 | 193 |
| 194 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 194 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| 195 LocationSummary* locs = new LocationSummary(2, 0); | 195 const intptr_t kNumInputs = 2; |
| 196 locs->set_in(0, Location::RequiresRegister()); | 196 if (operands_class_id() == kSmi) { |
| 197 locs->set_in(1, Location::RequiresRegister()); | 197 const intptr_t kNumTemps = 1; |
| 198 locs->set_out(Location::RegisterLocation(RAX)); | 198 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 199 return locs; | 199 locs->set_in(0, Location::RequiresRegister()); |
| 200 locs->set_in(1, Location::RequiresRegister()); | |
| 201 locs->set_temp(0, Location::RequiresRegister()); | |
| 202 locs->set_out(Location::RequiresRegister()); | |
| 203 return locs; | |
| 204 } else { | |
| 205 const intptr_t kNumTemps = 0; | |
| 206 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | |
| 207 locs->set_in(0, Location::RequiresRegister()); | |
| 208 locs->set_in(1, Location::RequiresRegister()); | |
| 209 locs->set_out(Location::RegisterLocation(RAX)); | |
| 210 return locs; | |
| 211 } | |
| 200 } | 212 } |
| 201 | 213 |
| 202 | 214 |
| 203 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 215 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 216 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 217 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 218 if (operands_class_id() == kObject) { | |
| 219 Register left = locs()->in(0).reg(); | |
| 220 Register right = locs()->in(1).reg(); | |
| 221 Register result = locs()->out().reg(); | |
| 222 const Immediate raw_null = | |
| 223 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 224 // Inline null comparison. | |
| 225 __ cmpq(left, raw_null); | |
| 226 Label not_null, done, is_true; | |
| 227 __ j(NOT_EQUAL, ¬_null, Assembler::kNearJump); | |
| 228 __ cmpq(left, right); | |
| 229 __ j(EQUAL, &is_true, Assembler::kNearJump); | |
| 230 __ LoadObject(result, bool_false); | |
| 231 __ jmp(&done, Assembler::kNearJump); | |
| 232 __ Bind(&is_true); | |
| 233 __ LoadObject(result, bool_true); | |
| 234 __ jmp(&done, Assembler::kNearJump); | |
| 235 | |
| 236 __ Bind(¬_null); | |
| 237 __ pushq(left); | |
| 238 __ pushq(right); | |
| 239 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 240 cid(), | |
| 241 token_index(), | |
| 242 try_index()); | |
| 243 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); | |
| 244 const int kNumberOfArguments = 2; | |
| 245 const Array& kNoArgumentNames = Array::Handle(); | |
| 246 const int kNumArgumentsChecked = 2; | |
| 247 | |
| 248 compiler->GenerateInstanceCall(cid(), | |
| 249 token_index(), | |
| 250 try_index(), | |
| 251 operator_name, | |
| 252 kNumberOfArguments, | |
| 253 kNoArgumentNames, | |
| 254 kNumArgumentsChecked); | |
| 255 ASSERT(locs()->out().reg() == RAX); | |
| 256 __ Bind(&done); | |
| 257 return; | |
| 258 } | |
| 259 if (operands_class_id() == kSmi) { | |
| 260 // TODO(srdjan): Should we always include NULL test (common case)? | |
| 261 Register left = locs()->in(0).reg(); | |
| 262 Register right = locs()->in(1).reg(); | |
| 263 Register result = locs()->out().reg(); | |
| 264 Register temp = locs()->temp(0).reg(); | |
| 265 Label* deopt = compiler->AddDeoptStub(cid(), | |
| 266 token_index(), | |
| 267 try_index(), | |
| 268 kDeoptSmiCompareSmis, | |
| 269 left, | |
| 270 right); | |
| 271 __ movq(temp, left); | |
| 272 __ orq(temp, right); | |
| 273 __ testq(temp, Immediate(kSmiTagMask)); | |
| 274 __ j(NOT_ZERO, deopt); | |
| 275 __ cmpq(left, right); | |
| 276 Label load_true, done; | |
| 277 __ j(EQUAL, &load_true, Assembler::kNearJump); | |
| 278 __ LoadObject(result, bool_false); | |
| 279 __ jmp(&done, Assembler::kNearJump); | |
| 280 __ Bind(&load_true); | |
| 281 __ LoadObject(result, bool_true); | |
| 282 __ Bind(&done); | |
| 283 return; | |
| 284 } | |
| 285 UNIMPLEMENTED(); | |
| 204 Register left = locs()->in(0).reg(); | 286 Register left = locs()->in(0).reg(); |
|
Vyacheslav Egorov (Google)
2012/06/13 09:02:27
Please remove dead code.
srdjan
2012/06/13 18:34:24
Done.
| |
| 205 Register right = locs()->in(1).reg(); | 287 Register right = locs()->in(1).reg(); |
| 206 Register result = locs()->out().reg(); | 288 Register result = locs()->out().reg(); |
| 207 ASSERT(locs()->out().reg() == RAX); | 289 ASSERT(locs()->out().reg() == RAX); |
| 208 | 290 |
| 209 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 210 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 211 const Immediate raw_null = | 291 const Immediate raw_null = |
| 212 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 292 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 213 Label done, load_true, non_null_compare; | 293 Label done, load_true, non_null_compare; |
| 214 | 294 |
| 215 __ cmpq(left, raw_null); | 295 __ cmpq(left, raw_null); |
| 216 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); | 296 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
| 217 // Comparison with NULL is "===". | 297 // Comparison with NULL is "===". |
| 218 __ cmpq(left, right); | 298 __ cmpq(left, right); |
| 219 __ j(EQUAL, &load_true, Assembler::kNearJump); | 299 __ j(EQUAL, &load_true, Assembler::kNearJump); |
| 220 __ LoadObject(result, bool_false); | 300 __ LoadObject(result, bool_false); |
| (...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1381 } else { | 1461 } else { |
| 1382 UNREACHABLE(); | 1462 UNREACHABLE(); |
| 1383 } | 1463 } |
| 1384 } | 1464 } |
| 1385 | 1465 |
| 1386 } // namespace dart | 1466 } // namespace dart |
| 1387 | 1467 |
| 1388 #undef __ | 1468 #undef __ |
| 1389 | 1469 |
| 1390 #endif // defined TARGET_ARCH_X64 | 1470 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |