Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 13502002: Support FrameLookup vm test on ARM, requiring among other things: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 160 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
161 summary->set_in(0, Location::RegisterLocation(R0)); // Value. 161 summary->set_in(0, Location::RegisterLocation(R0)); // Value.
162 summary->set_in(1, Location::RegisterLocation(R1)); // Instantiator. 162 summary->set_in(1, Location::RegisterLocation(R1)); // Instantiator.
163 summary->set_in(2, Location::RegisterLocation(R2)); // Type arguments. 163 summary->set_in(2, Location::RegisterLocation(R2)); // Type arguments.
164 summary->set_out(Location::RegisterLocation(R0)); 164 summary->set_out(Location::RegisterLocation(R0));
165 return summary; 165 return summary;
166 } 166 }
167 167
168 168
169 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 169 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const {
170 UNIMPLEMENTED(); 170 const intptr_t kNumInputs = 1;
171 return NULL; 171 const intptr_t kNumTemps = 0;
172 LocationSummary* locs =
173 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
174 locs->set_in(0, Location::RegisterLocation(R0));
175 locs->set_out(Location::RegisterLocation(R0));
176 return locs;
177 }
178
179
180 static void EmitAssertBoolean(Register reg,
181 intptr_t token_pos,
182 intptr_t deopt_id,
183 LocationSummary* locs,
184 FlowGraphCompiler* compiler) {
185 // Check that the type of the value is allowed in conditional context.
186 // Call the runtime if the object is not bool::true or bool::false.
187 ASSERT(locs->always_calls());
188 Label done;
189 __ CompareObject(reg, Bool::True());
190 __ b(&done, EQ);
191 __ CompareObject(reg, Bool::False());
192 __ b(&done, EQ);
193
194 __ Push(reg); // Push the source object.
195 compiler->GenerateCallRuntime(token_pos,
196 deopt_id,
197 kConditionTypeErrorRuntimeEntry,
198 locs);
199 // We should never return here.
200 __ bkpt(0);
201 __ Bind(&done);
172 } 202 }
173 203
174 204
175 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 205 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
176 UNIMPLEMENTED(); 206 Register obj = locs()->in(0).reg();
207 Register result = locs()->out().reg();
208
209 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
210 ASSERT(obj == result);
177 } 211 }
178 212
179 213
180 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { 214 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const {
181 UNIMPLEMENTED(); 215 UNIMPLEMENTED();
182 return NULL; 216 return NULL;
183 } 217 }
184 218
185 219
186 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 220 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
187 UNIMPLEMENTED(); 221 UNIMPLEMENTED();
188 } 222 }
189 223
190 224
191 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 225 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
192 UNIMPLEMENTED(); 226 const intptr_t kNumInputs = 2;
193 return NULL; 227 const bool is_checked_strict_equal =
228 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
229 if (receiver_class_id() == kMintCid) {
230 const intptr_t kNumTemps = 1;
231 LocationSummary* locs =
232 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
233 locs->set_in(0, Location::RequiresFpuRegister());
234 locs->set_in(1, Location::RequiresFpuRegister());
235 locs->set_temp(0, Location::RequiresRegister());
236 locs->set_out(Location::RequiresRegister());
237 return locs;
238 }
239 if (receiver_class_id() == kDoubleCid) {
240 const intptr_t kNumTemps = 0;
241 LocationSummary* locs =
242 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
243 locs->set_in(0, Location::RequiresFpuRegister());
244 locs->set_in(1, Location::RequiresFpuRegister());
245 locs->set_out(Location::RequiresRegister());
246 return locs;
247 }
248 if (receiver_class_id() == kSmiCid) {
249 const intptr_t kNumTemps = 0;
250 LocationSummary* locs =
251 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
252 locs->set_in(0, Location::RegisterOrConstant(left()));
253 // Only one input can be a constant operand. The case of two constant
254 // operands should be handled by constant propagation.
255 locs->set_in(1, locs->in(0).IsConstant()
256 ? Location::RequiresRegister()
257 : Location::RegisterOrConstant(right()));
258 locs->set_out(Location::RequiresRegister());
259 return locs;
260 }
261 if (is_checked_strict_equal) {
262 const intptr_t kNumTemps = 1;
263 LocationSummary* locs =
264 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
265 locs->set_in(0, Location::RequiresRegister());
266 locs->set_in(1, Location::RequiresRegister());
267 locs->set_temp(0, Location::RequiresRegister());
268 locs->set_out(Location::RequiresRegister());
269 return locs;
270 }
271 if (IsPolymorphic()) {
272 const intptr_t kNumTemps = 1;
273 LocationSummary* locs =
274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
275 UNIMPLEMENTED(); // TODO(regis): Verify register allocation.
276 return locs;
277 }
278 const intptr_t kNumTemps = 1;
279 LocationSummary* locs =
280 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
281 locs->set_in(0, Location::RegisterLocation(R1));
282 locs->set_in(1, Location::RegisterLocation(R0));
283 locs->set_temp(0, Location::RegisterLocation(R6));
284 locs->set_out(Location::RegisterLocation(R0));
285 return locs;
286 }
287
288
289 // R1: left.
290 // R0: right.
291 // Uses R6 to load ic_call_data.
292 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
293 intptr_t deopt_id,
294 intptr_t token_pos,
295 Token::Kind kind,
296 LocationSummary* locs,
297 const ICData& original_ic_data) {
298 if (!compiler->is_optimizing()) {
299 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
300 deopt_id,
301 token_pos);
302 }
303 const int kNumberOfArguments = 2;
304 const Array& kNoArgumentNames = Array::Handle();
305 const int kNumArgumentsChecked = 2;
306
307 Label check_identity;
308 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
309 __ cmp(R1, ShifterOperand(IP));
310 __ b(&check_identity, EQ);
311 __ cmp(R0, ShifterOperand(IP));
312 __ b(&check_identity, EQ);
313
314 ICData& equality_ic_data = ICData::ZoneHandle();
315 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
316 ASSERT(!original_ic_data.IsNull());
317 if (original_ic_data.NumberOfChecks() == 0) {
318 // IC call for reoptimization populates original ICData.
319 equality_ic_data = original_ic_data.raw();
320 } else {
321 // Megamorphic call.
322 equality_ic_data = original_ic_data.AsUnaryClassChecks();
323 }
324 } else {
325 equality_ic_data = ICData::New(compiler->parsed_function().function(),
326 Symbols::EqualOperator(),
327 deopt_id,
328 kNumArgumentsChecked);
329 }
330 __ PushList((1 << R0) | (1 << R1));
331 compiler->GenerateInstanceCall(deopt_id,
332 token_pos,
333 kNumberOfArguments,
334 kNoArgumentNames,
335 locs,
336 equality_ic_data);
337 Label check_ne;
338 __ b(&check_ne);
339
340 __ Bind(&check_identity);
341 Label equality_done;
342 if (compiler->is_optimizing()) {
343 // No need to update IC data.
344 Label is_true;
345 __ cmp(R0, ShifterOperand(R1));
346 __ b(&is_true, EQ);
347 __ LoadObject(R0, (kind == Token::kEQ) ? Bool::False() : Bool::True());
348 __ b(&equality_done);
349 __ Bind(&is_true);
350 __ LoadObject(R0, (kind == Token::kEQ) ? Bool::True() : Bool::False());
351 if (kind == Token::kNE) {
352 // Skip not-equal result conversion.
353 __ b(&equality_done);
354 }
355 } else {
356 // Call stub, load IC data in register. The stub will update ICData if
357 // necessary.
358 Register ic_data_reg = locs->temp(0).reg();
359 ASSERT(ic_data_reg == R6); // Stub depends on it.
360 __ LoadObject(ic_data_reg, equality_ic_data);
361 // Pass left in R1 and right in R0.
362 compiler->GenerateCall(token_pos,
363 &StubCode::EqualityWithNullArgLabel(),
364 PcDescriptors::kOther,
365 locs);
366 }
367 __ Bind(&check_ne);
368 if (kind == Token::kNE) {
369 Label false_label, true_label, done;
370 // Negate the condition: true label returns false and vice versa.
371 __ CompareObject(R0, Bool::True());
372 __ b(&true_label, EQ);
373 __ Bind(&false_label);
zra 2013/04/03 17:39:47 Nothing branches to this label.
regis 2013/04/03 20:06:07 Removed here and on other platforms.
374 __ LoadObject(R0, Bool::True());
375 __ b(&done);
376 __ Bind(&true_label);
377 __ LoadObject(R0, Bool::False());
378 __ Bind(&done);
379 }
380 __ Bind(&equality_done);
381 }
382
383
384 // Emit code when ICData's targets are all Object == (which is ===).
385 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler,
386 const ICData& ic_data,
387 const LocationSummary& locs,
388 Token::Kind kind,
389 BranchInstr* branch,
390 intptr_t deopt_id) {
391 UNIMPLEMENTED();
392 }
393
394
395 // First test if receiver is NULL, in which case === is applied.
396 // If type feedback was provided (lists of <class-id, target>), do a
397 // type by type check (either === or static call to the operator.
398 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
399 LocationSummary* locs,
400 Token::Kind kind,
401 BranchInstr* branch,
402 const ICData& ic_data,
403 intptr_t deopt_id,
404 intptr_t token_pos) {
405 UNIMPLEMENTED();
406 }
407
408
409 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
410 const LocationSummary& locs,
411 Token::Kind kind,
412 BranchInstr* branch) {
413 UNIMPLEMENTED();
414 }
415
416
417 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
418 const LocationSummary& locs,
419 Token::Kind kind,
420 BranchInstr* branch) {
421 UNIMPLEMENTED();
422 }
423
424
425 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
426 const LocationSummary& locs,
427 Token::Kind kind,
428 BranchInstr* branch) {
429 UNIMPLEMENTED();
194 } 430 }
195 431
196 432
197 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 433 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
198 UNIMPLEMENTED(); 434 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
435 BranchInstr* kNoBranch = NULL;
436 if (receiver_class_id() == kSmiCid) {
437 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
438 return;
439 }
440 if (receiver_class_id() == kMintCid) {
441 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
442 return;
443 }
444 if (receiver_class_id() == kDoubleCid) {
445 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
446 return;
447 }
448 const bool is_checked_strict_equal =
449 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
450 if (is_checked_strict_equal) {
451 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
452 deopt_id());
453 return;
454 }
455 if (IsPolymorphic()) {
456 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(),
457 deopt_id(), token_pos());
458 return;
459 }
460 Register left = locs()->in(0).reg();
461 Register right = locs()->in(1).reg();
462 ASSERT(left == R1);
463 ASSERT(right == R0);
464 EmitEqualityAsInstanceCall(compiler,
465 deopt_id(),
466 token_pos(),
467 kind(),
468 locs(),
469 *ic_data());
470 ASSERT(locs()->out().reg() == R0);
199 } 471 }
200 472
201 473
202 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 474 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
203 BranchInstr* branch) { 475 BranchInstr* branch) {
204 UNIMPLEMENTED(); 476 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
205 } 477 if (receiver_class_id() == kSmiCid) {
206 478 // Deoptimizes if both arguments not Smi.
207 479 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
480 return;
481 }
482 if (receiver_class_id() == kMintCid) {
483 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
484 return;
485 }
486 if (receiver_class_id() == kDoubleCid) {
487 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
488 return;
489 }
490 const bool is_checked_strict_equal =
491 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
492 if (is_checked_strict_equal) {
493 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
494 deopt_id());
495 return;
496 }
497 if (IsPolymorphic()) {
498 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(),
499 deopt_id(), token_pos());
500 return;
501 }
502 Register left = locs()->in(0).reg();
503 Register right = locs()->in(1).reg();
504 ASSERT(left == R1);
505 ASSERT(right == R0);
506 EmitEqualityAsInstanceCall(compiler,
507 deopt_id(),
508 token_pos(),
509 Token::kEQ, // kNE reverse occurs at branch.
510 locs(),
511 *ic_data());
512 if (branch->is_checked()) {
513 EmitAssertBoolean(R0, token_pos(), deopt_id(), locs(), compiler);
514 }
515 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
516 __ CompareObject(R0, Bool::True());
517 branch->EmitBranchOnCondition(compiler, branch_condition);
518 }
519
520
208 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 521 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
209 UNIMPLEMENTED(); 522 UNIMPLEMENTED();
210 return NULL; 523 return NULL;
211 } 524 }
212 525
213 526
214 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 527 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
215 UNIMPLEMENTED(); 528 UNIMPLEMENTED();
216 } 529 }
217 530
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 } 997 }
685 998
686 999
687 LocationSummary* BranchInstr::MakeLocationSummary() const { 1000 LocationSummary* BranchInstr::MakeLocationSummary() const {
688 UNREACHABLE(); 1001 UNREACHABLE();
689 return NULL; 1002 return NULL;
690 } 1003 }
691 1004
692 1005
693 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1006 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
694 UNIMPLEMENTED(); 1007 comparison()->EmitBranchCode(compiler, this);
695 } 1008 }
696 1009
697 1010
698 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 1011 LocationSummary* CheckClassInstr::MakeLocationSummary() const {
699 UNIMPLEMENTED(); 1012 UNIMPLEMENTED();
700 return NULL; 1013 return NULL;
701 } 1014 }
702 1015
703 1016
704 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1017 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 return NULL; 1113 return NULL;
801 } 1114 }
802 1115
803 1116
804 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1117 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
805 UNIMPLEMENTED(); 1118 UNIMPLEMENTED();
806 } 1119 }
807 1120
808 1121
809 LocationSummary* GotoInstr::MakeLocationSummary() const { 1122 LocationSummary* GotoInstr::MakeLocationSummary() const {
810 UNIMPLEMENTED(); 1123 return new LocationSummary(0, 0, LocationSummary::kNoCall);
811 return NULL;
812 } 1124 }
813 1125
814 1126
815 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1127 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
816 UNIMPLEMENTED(); 1128 // Add deoptimization descriptor for deoptimizing instructions
1129 // that may be inserted before this instruction.
1130 if (!compiler->is_optimizing()) {
1131 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
1132 GetDeoptId(),
1133 0); // No token position.
1134 }
1135
1136 if (HasParallelMove()) {
1137 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1138 }
1139
1140 // We can fall through if the successor is the next block in the list.
1141 // Otherwise, we need a jump.
1142 if (!compiler->CanFallThroughTo(successor())) {
1143 __ b(compiler->GetJumpLabel(successor()));
1144 }
1145 }
1146
1147
1148 static Condition NegateCondition(Condition condition) {
1149 switch (condition) {
1150 case EQ: return NE;
1151 case NE: return EQ;
1152 case LT: return GE;
1153 case LE: return GT;
1154 case GT: return LE;
1155 case GE: return LT;
1156 case CC: return CS;
1157 case LS: return HI;
1158 case HI: return LS;
1159 case CS: return CC;
1160 default:
1161 OS::Print("Error %d\n", condition);
1162 UNIMPLEMENTED();
1163 return EQ;
1164 }
817 } 1165 }
818 1166
819 1167
820 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler, 1168 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
821 bool value) { 1169 bool value) {
822 UNIMPLEMENTED(); 1170 if (value && !compiler->CanFallThroughTo(true_successor())) {
1171 __ b(compiler->GetJumpLabel(true_successor()));
1172 } else if (!value && !compiler->CanFallThroughTo(false_successor())) {
1173 __ b(compiler->GetJumpLabel(false_successor()));
1174 }
823 } 1175 }
824 1176
825 1177
826 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler, 1178 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
827 Condition true_condition) { 1179 Condition true_condition) {
828 UNIMPLEMENTED(); 1180 if (compiler->CanFallThroughTo(false_successor())) {
1181 // If the next block is the false successor we will fall through to it.
1182 __ b(compiler->GetJumpLabel(true_successor()), true_condition);
1183 } else {
1184 // If the next block is the true successor we negate comparison and fall
1185 // through to it.
1186 Condition false_condition = NegateCondition(true_condition);
1187 __ b(compiler->GetJumpLabel(false_successor()), false_condition);
1188
1189 // Fall through or jump to the true successor.
1190 if (!compiler->CanFallThroughTo(true_successor())) {
1191 __ b(compiler->GetJumpLabel(true_successor()));
1192 }
1193 }
829 } 1194 }
830 1195
831 1196
832 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 1197 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
833 UNIMPLEMENTED(); 1198 UNIMPLEMENTED();
834 return NULL; 1199 return NULL;
835 } 1200 }
836 1201
837 1202
838 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1203 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
839 UNIMPLEMENTED(); 1204 UNIMPLEMENTED();
840 } 1205 }
841 1206
842 1207
843 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { 1208 LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
844 UNIMPLEMENTED(); 1209 const intptr_t kNumInputs = 2;
845 return NULL; 1210 const intptr_t kNumTemps = 0;
1211 LocationSummary* locs =
1212 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1213 locs->set_in(0, Location::RegisterOrConstant(left()));
1214 locs->set_in(1, Location::RegisterOrConstant(right()));
1215 locs->set_out(Location::RequiresRegister());
1216 return locs;
846 } 1217 }
847 1218
848 1219
1220 // Special code for numbers (compare values instead of references.)
849 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1221 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
850 UNIMPLEMENTED(); 1222 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1223 Location left = locs()->in(0);
1224 Location right = locs()->in(1);
1225 if (left.IsConstant() && right.IsConstant()) {
1226 // TODO(vegorov): should be eliminated earlier by constant propagation.
zra 2013/04/03 17:39:47 Unless constant propagation/folding is really bad,
regis 2013/04/03 20:06:07 I cannot answer for Slava :-) Since there is alrea
1227 const bool result = (kind() == Token::kEQ_STRICT) ?
1228 left.constant().raw() == right.constant().raw() :
1229 left.constant().raw() != right.constant().raw();
1230 __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
1231 return;
1232 }
1233 if (left.IsConstant()) {
1234 compiler->EmitEqualityRegConstCompare(right.reg(),
1235 left.constant(),
1236 needs_number_check());
1237 } else if (right.IsConstant()) {
1238 compiler->EmitEqualityRegConstCompare(left.reg(),
1239 right.constant(),
1240 needs_number_check());
1241 } else {
1242 compiler->EmitEqualityRegRegCompare(left.reg(),
1243 right.reg(),
1244 needs_number_check());
1245 }
1246
1247 Register result = locs()->out().reg();
1248 Label load_true, done;
1249 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
1250 __ b(&load_true, true_condition);
1251 __ LoadObject(result, Bool::False());
1252 __ b(&done);
1253 __ Bind(&load_true);
1254 __ LoadObject(result, Bool::True());
1255 __ Bind(&done);
851 } 1256 }
852 1257
853 1258
854 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1259 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
855 BranchInstr* branch) { 1260 BranchInstr* branch) {
856 UNIMPLEMENTED(); 1261 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1262 Location left = locs()->in(0);
1263 Location right = locs()->in(1);
1264 if (left.IsConstant() && right.IsConstant()) {
1265 // TODO(vegorov): should be eliminated earlier by constant propagation.
zra 2013/04/03 17:39:47 Here too?
regis 2013/04/03 20:06:07 ditto
1266 const bool result = (kind() == Token::kEQ_STRICT) ?
1267 left.constant().raw() == right.constant().raw() :
1268 left.constant().raw() != right.constant().raw();
1269 branch->EmitBranchOnValue(compiler, result);
1270 return;
1271 }
1272 if (left.IsConstant()) {
1273 compiler->EmitEqualityRegConstCompare(right.reg(),
1274 left.constant(),
1275 needs_number_check());
1276 } else if (right.IsConstant()) {
1277 compiler->EmitEqualityRegConstCompare(left.reg(),
1278 right.constant(),
1279 needs_number_check());
1280 } else {
1281 compiler->EmitEqualityRegRegCompare(left.reg(),
1282 right.reg(),
1283 needs_number_check());
1284 }
1285
1286 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
1287 branch->EmitBranchOnCondition(compiler, true_condition);
857 } 1288 }
858 1289
859 1290
860 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1291 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
861 UNIMPLEMENTED(); 1292 UNIMPLEMENTED();
862 } 1293 }
863 1294
864 1295
865 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 1296 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
866 UNIMPLEMENTED(); 1297 UNIMPLEMENTED();
(...skipping 22 matching lines...) Expand all
889 return NULL; 1320 return NULL;
890 } 1321 }
891 1322
892 1323
893 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1324 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
894 UNIMPLEMENTED(); 1325 UNIMPLEMENTED();
895 } 1326 }
896 1327
897 1328
898 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 1329 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
899 UNIMPLEMENTED(); 1330 return MakeCallSummary();
900 return NULL;
901 } 1331 }
902 1332
903 1333
904 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1334 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
905 UNIMPLEMENTED(); 1335 const Class& cls = Class::ZoneHandle(constructor().Owner());
1336 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
1337 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1338 compiler->GenerateCall(token_pos(),
1339 &label,
1340 PcDescriptors::kOther,
1341 locs());
1342 __ Drop(ArgumentCount()); // Discard arguments.
906 } 1343 }
907 1344
908 1345
909 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { 1346 LocationSummary* CreateClosureInstr::MakeLocationSummary() const {
910 UNIMPLEMENTED(); 1347 UNIMPLEMENTED();
911 return NULL; 1348 return NULL;
912 } 1349 }
913 1350
914 1351
915 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1352 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
916 UNIMPLEMENTED(); 1353 UNIMPLEMENTED();
917 } 1354 }
918 1355
919 } // namespace dart 1356 } // namespace dart
920 1357
921 #endif // defined TARGET_ARCH_ARM 1358 #endif // defined TARGET_ARCH_ARM
922 1359
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698