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

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

Issue 14431004: Implements missing features to run Hello, World in checked mode on MIPS. (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
« no previous file with comments | « runtime/tests/vm/vm.status ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 const Register kTempReg = kNoRegister; 277 const Register kTempReg = kNoRegister;
278 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 278 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
279 kInstanceReg, 279 kInstanceReg,
280 kTypeArgumentsReg, 280 kTypeArgumentsReg,
281 kTempReg, 281 kTempReg,
282 is_instance_lbl, 282 is_instance_lbl,
283 is_not_instance_lbl); 283 is_not_instance_lbl);
284 } 284 }
285 285
286 286
287 // Generates inlined check if 'type' is a type parameter or type itself
288 // A0: instance (preserved).
287 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 289 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
288 intptr_t token_pos, 290 intptr_t token_pos,
289 const AbstractType& type, 291 const AbstractType& type,
290 Label* is_instance_lbl, 292 Label* is_instance_lbl,
291 Label* is_not_instance_lbl) { 293 Label* is_not_instance_lbl) {
292 UNIMPLEMENTED(); 294 __ Comment("UninstantiatedTypeTest");
293 return NULL; 295 ASSERT(!type.IsInstantiated());
296 // Skip check if destination is a dynamic type.
297 if (type.IsTypeParameter()) {
298 const TypeParameter& type_param = TypeParameter::Cast(type);
299 // Load instantiator (or null) and instantiator type arguments on stack.
300 __ lw(A1, Address(SP, 0)); // Get instantiator type arguments.
301 // A1: instantiator type arguments.
302 // Check if type argument is dynamic.
303 __ BranchEqual(A1, reinterpret_cast<intptr_t>(Object::null()),
304 is_instance_lbl);
305 // Can handle only type arguments that are instances of TypeArguments.
306 // (runtime checks canonicalize type arguments).
307 Label fall_through;
308 __ LoadClassId(T2, A1);
309 __ BranchNotEqual(T2, kTypeArgumentsCid, &fall_through);
310 __ lw(T2,
311 FieldAddress(A1, TypeArguments::type_at_offset(type_param.index())));
312 // R2: concrete type of type.
313 // Check if type argument is dynamic.
314 __ BranchEqual(T2, Type::ZoneHandle(Type::DynamicType()), is_instance_lbl);
315 __ BranchEqual(T2, reinterpret_cast<intptr_t>(Object::null()),
316 is_instance_lbl);
317 const Type& object_type = Type::ZoneHandle(Type::ObjectType());
318 __ BranchEqual(T2, object_type, is_instance_lbl);
319
320 // For Smi check quickly against int and num interfaces.
321 Label not_smi;
322 __ andi(CMPRES, A0, Immediate(kSmiTagMask));
323 __ bne(CMPRES, ZR, &not_smi); // Value is Smi?
324 __ BranchEqual(T2, Type::ZoneHandle(Type::IntType()), is_instance_lbl);
325 __ BranchEqual(T2, Type::ZoneHandle(Type::Number()), is_instance_lbl);
326
327 // Smi must be handled in runtime.
328 __ b(&fall_through);
329
330 __ Bind(&not_smi);
331 // T1: instantiator type arguments.
332 // A0: instance.
333 const Register kInstanceReg = A0;
334 const Register kTypeArgumentsReg = A1;
335 const Register kTempReg = kNoRegister;
336 const SubtypeTestCache& type_test_cache =
337 SubtypeTestCache::ZoneHandle(
338 GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
339 kInstanceReg,
340 kTypeArgumentsReg,
341 kTempReg,
342 is_instance_lbl,
343 is_not_instance_lbl));
344 __ Bind(&fall_through);
345 return type_test_cache.raw();
346 }
347 if (type.IsType()) {
348 const Register kInstanceReg = A0;
349 const Register kTypeArgumentsReg = A1;
350 __ andi(CMPRES, kInstanceReg, Immediate(kSmiTagMask));
351 __ beq(CMPRES, ZR, is_not_instance_lbl); // Is instance Smi?
352 __ lw(kTypeArgumentsReg, Address(SP, 0)); // Instantiator type args.
353 // Uninstantiated type class is known at compile time, but the type
354 // arguments are determined at runtime by the instantiator.
355 const Register kTempReg = kNoRegister;
356 return GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
357 kInstanceReg,
358 kTypeArgumentsReg,
359 kTempReg,
360 is_instance_lbl,
361 is_not_instance_lbl);
362 }
363 return SubtypeTestCache::null();
294 } 364 }
295 365
296 366
297 // Inputs: 367 // Inputs:
298 // - A0: instance being type checked (preserved). 368 // - A0: instance being type checked (preserved).
299 // - A1: optional instantiator type arguments (preserved). 369 // - A1: optional instantiator type arguments (preserved).
300 // Returns: 370 // Returns:
301 // - preserved instance in A0 and optional instantiator type arguments in A1. 371 // - preserved instance in A0 and optional instantiator type arguments in A1.
302 // Clobbers: T0, T1, T2 372 // Clobbers: T0, T1, T2
303 // Note that this inlined code must be followed by the runtime_call code, as it 373 // Note that this inlined code must be followed by the runtime_call code, as it
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 __ addiu(SP, SP, Immediate(2 * kWordSize)); 509 __ addiu(SP, SP, Immediate(2 * kWordSize));
440 return; 510 return;
441 } 511 }
442 512
443 // Generate inline type check, linking to runtime call if not assignable. 513 // Generate inline type check, linking to runtime call if not assignable.
444 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 514 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
445 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 515 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
446 &is_assignable, &runtime_call); 516 &is_assignable, &runtime_call);
447 517
448 __ Bind(&runtime_call); 518 __ Bind(&runtime_call);
449 // Load instantiator and its type arguments. 519 // Load instantiator (A2) and its type arguments (A1).
450 __ lw(A1, Address(SP, 0 * kWordSize)); 520 __ lw(A1, Address(SP, 0 * kWordSize));
451 __ lw(A2, Address(SP, 1 * kWordSize)); 521 __ lw(A2, Address(SP, 1 * kWordSize));
452 522
453 __ addiu(SP, SP, Immediate(-7 * kWordSize)); 523 __ addiu(SP, SP, Immediate(-7 * kWordSize));
454 __ LoadObject(TMP1, Object::ZoneHandle()); 524 __ LoadObject(TMP1, Object::ZoneHandle());
455 __ sw(TMP1, Address(SP, 6 * kWordSize)); // Make room for the result. 525 __ sw(TMP1, Address(SP, 6 * kWordSize)); // Make room for the result.
456 __ sw(A0, Address(SP, 5 * kWordSize)); // Push the source object. 526 __ sw(A0, Address(SP, 5 * kWordSize)); // Push the source object.
457 __ LoadObject(TMP1, dst_type); 527 __ LoadObject(TMP1, dst_type);
458 __ sw(TMP1, Address(SP, 4 * kWordSize)); // Push the type of the destination. 528 __ sw(TMP1, Address(SP, 4 * kWordSize)); // Push the type of the destination.
459 __ sw(A2, Address(SP, 3 * kWordSize)); // Push instantiator. 529 __ sw(A2, Address(SP, 3 * kWordSize)); // Push instantiator.
460 __ sw(A1, Address(SP, 2 * kWordSize)); // Push type arguments. 530 __ sw(A1, Address(SP, 2 * kWordSize)); // Push type arguments.
461 __ LoadObject(TMP1, dst_name); 531 __ LoadObject(TMP1, dst_name);
462 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the name of the destination. 532 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the name of the destination.
533 __ LoadObject(T0, test_cache);
463 __ sw(T0, Address(SP, 0 * kWordSize)); 534 __ sw(T0, Address(SP, 0 * kWordSize));
464 535
465 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs); 536 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
466 // Pop the parameters supplied to the runtime entry. The result of the 537 // Pop the parameters supplied to the runtime entry. The result of the
467 // type check runtime call is the checked value. 538 // type check runtime call is the checked value.
468 __ lw(A0, Address(SP, 6 * kWordSize)); 539 __ lw(A0, Address(SP, 6 * kWordSize));
469 __ addiu(SP, SP, Immediate(7 * kWordSize)); 540 __ addiu(SP, SP, Immediate(7 * kWordSize));
470 541
471 __ Bind(&is_assignable); 542 __ Bind(&is_assignable);
472 // Restore instantiator and its type arguments. 543 // Restore instantiator and its type arguments.
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 __ AddImmediate(SP, kDoubleSize); 1533 __ AddImmediate(SP, kDoubleSize);
1463 } 1534 }
1464 1535
1465 1536
1466 #undef __ 1537 #undef __
1467 1538
1468 1539
1469 } // namespace dart 1540 } // namespace dart
1470 1541
1471 #endif // defined TARGET_ARCH_MIPS 1542 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/tests/vm/vm.status ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698