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_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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 kConditionTypeErrorRuntimeEntry); | 176 kConditionTypeErrorRuntimeEntry); |
| 177 // We should never return here. | 177 // We should never return here. |
| 178 __ int3(); | 178 __ int3(); |
| 179 | 179 |
| 180 __ Bind(&done); | 180 __ Bind(&done); |
| 181 ASSERT(obj == result); | 181 ASSERT(obj == result); |
| 182 } | 182 } |
| 183 | 183 |
| 184 | 184 |
| 185 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 185 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| 186 LocationSummary* locs = new LocationSummary(2, 0); | 186 const intptr_t kNumInputs = 2; |
| 187 locs->set_in(0, Location::RequiresRegister()); | 187 if (operands_class_id() == kSmi) { |
| 188 locs->set_in(1, Location::RequiresRegister()); | 188 const intptr_t kNumTemps = 1; |
| 189 locs->set_out(Location::RegisterLocation(EAX)); | 189 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 190 return locs; | 190 locs->set_in(0, Location::RequiresRegister()); |
| 191 locs->set_in(1, Location::RequiresRegister()); | |
| 192 locs->set_temp(0, Location::RequiresRegister()); | |
| 193 locs->set_out(Location::RequiresRegister()); | |
| 194 return locs; | |
| 195 } else { | |
| 196 const intptr_t kNumTemps = 0; | |
| 197 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | |
| 198 locs->set_in(0, Location::RequiresRegister()); | |
| 199 locs->set_in(1, Location::RequiresRegister()); | |
| 200 locs->set_out(Location::RegisterLocation(EAX)); | |
| 201 return locs; | |
| 202 } | |
| 191 } | 203 } |
| 192 | 204 |
| 193 | 205 |
| 194 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 206 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 195 Register left = locs()->in(0).reg(); | |
| 196 Register right = locs()->in(1).reg(); | |
| 197 Register result = locs()->out().reg(); | |
| 198 ASSERT(locs()->out().reg() == EAX); | |
| 199 | |
| 200 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 207 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 201 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 208 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 202 const Immediate raw_null = | 209 if (operands_class_id() == kObject) { |
| 203 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 210 Register left = locs()->in(0).reg(); |
|
Vyacheslav Egorov (Google)
2012/06/13 09:02:27
I think when instruction code is large enough it m
srdjan
2012/06/13 18:34:24
Done.
| |
| 204 Label done, load_true, non_null_compare; | 211 Register right = locs()->in(1).reg(); |
| 205 __ cmpl(left, raw_null); | 212 Register result = locs()->out().reg(); |
| 206 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); | 213 const Immediate raw_null = |
| 207 // Comparison with NULL is "===". | 214 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 208 __ cmpl(left, right); | 215 // Inline null comparison. |
| 209 __ j(EQUAL, &load_true, Assembler::kNearJump); | 216 __ cmpl(left, raw_null); |
| 210 __ LoadObject(result, bool_false); | 217 Label not_null, done, is_true; |
| 211 __ jmp(&done, Assembler::kNearJump); | 218 __ j(NOT_EQUAL, ¬_null, Assembler::kNearJump); |
| 212 __ Bind(&load_true); | 219 __ cmpl(left, right); |
| 213 __ LoadObject(result, bool_true); | 220 __ j(EQUAL, &is_true, Assembler::kNearJump); |
| 214 __ jmp(&done); | 221 __ LoadObject(result, bool_false); |
| 222 __ jmp(&done, Assembler::kNearJump); | |
| 223 __ Bind(&is_true); | |
| 224 __ LoadObject(result, bool_true); | |
| 225 __ jmp(&done, Assembler::kNearJump); | |
| 215 | 226 |
| 216 __ Bind(&non_null_compare); | 227 __ Bind(¬_null); |
| 217 __ pushl(left); | 228 __ pushl(left); |
| 218 __ pushl(right); | 229 __ pushl(right); |
| 219 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); | 230 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 220 const int kNumberOfArguments = 2; | 231 cid(), |
| 221 const Array& kNoArgumentNames = Array::Handle(); | 232 token_index(), |
| 222 const int kNumArgumentsChecked = 1; | 233 try_index()); |
| 234 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); | |
| 235 const int kNumberOfArguments = 2; | |
| 236 const Array& kNoArgumentNames = Array::Handle(); | |
| 237 const int kNumArgumentsChecked = 2; | |
| 223 | 238 |
| 224 compiler->GenerateInstanceCall(cid(), | 239 compiler->GenerateInstanceCall(cid(), |
| 225 token_index(), | 240 token_index(), |
| 226 try_index(), | 241 try_index(), |
| 227 operator_name, | 242 operator_name, |
| 228 kNumberOfArguments, | 243 kNumberOfArguments, |
| 229 kNoArgumentNames, | 244 kNoArgumentNames, |
| 230 kNumArgumentsChecked); | 245 kNumArgumentsChecked); |
| 231 __ Bind(&done); | 246 ASSERT(locs()->out().reg() == EAX); |
| 247 __ Bind(&done); | |
| 248 return; | |
| 249 } | |
| 250 if (operands_class_id() == kSmi) { | |
| 251 // TODO(srdjan): Should we always include NULL test (common case)? | |
| 252 Register left = locs()->in(0).reg(); | |
| 253 Register right = locs()->in(1).reg(); | |
| 254 Register result = locs()->out().reg(); | |
| 255 Register temp = locs()->temp(0).reg(); | |
| 256 Label* deopt = compiler->AddDeoptStub(cid(), | |
| 257 token_index(), | |
| 258 try_index(), | |
| 259 kDeoptSmiCompareSmis, | |
| 260 left, | |
| 261 right); | |
| 262 __ movl(temp, left); | |
| 263 __ orl(temp, right); | |
| 264 __ testl(temp, Immediate(kSmiTagMask)); | |
| 265 __ j(NOT_ZERO, deopt); | |
| 266 __ cmpl(left, right); | |
| 267 Label load_true, done; | |
| 268 __ j(EQUAL, &load_true, Assembler::kNearJump); | |
| 269 __ LoadObject(result, bool_false); | |
| 270 __ jmp(&done, Assembler::kNearJump); | |
| 271 __ Bind(&load_true); | |
| 272 __ LoadObject(result, bool_true); | |
| 273 __ Bind(&done); | |
| 274 return; | |
| 275 } | |
| 232 } | 276 } |
| 233 | 277 |
| 234 | 278 |
| 235 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 279 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 236 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) { | 280 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) { |
| 237 const intptr_t kNumInputs = 2; | 281 const intptr_t kNumInputs = 2; |
| 238 const intptr_t kNumTemps = 1; | 282 const intptr_t kNumTemps = 1; |
| 239 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 283 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 240 summary->set_in(0, Location::RequiresRegister()); | 284 summary->set_in(0, Location::RequiresRegister()); |
| 241 summary->set_in(1, Location::RequiresRegister()); | 285 summary->set_in(1, Location::RequiresRegister()); |
| (...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1349 __ movl(result, EAX); | 1393 __ movl(result, EAX); |
| 1350 __ popl(temp); | 1394 __ popl(temp); |
| 1351 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 1395 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
| 1352 __ DoubleNegate(XMM0); | 1396 __ DoubleNegate(XMM0); |
| 1353 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1397 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1354 } else { | 1398 } else { |
| 1355 UNREACHABLE(); | 1399 UNREACHABLE(); |
| 1356 } | 1400 } |
| 1357 } | 1401 } |
| 1358 | 1402 |
| 1359 | |
| 1360 } // namespace dart | 1403 } // namespace dart |
| 1361 | 1404 |
| 1362 #undef __ | 1405 #undef __ |
| 1363 | 1406 |
| 1364 #endif // defined TARGET_ARCH_X64 | 1407 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |