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

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

Issue 513213002: Generate some intrinsics using our IR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 6 years, 3 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_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/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, enable_type_checks); 18 DECLARE_FLAG(bool, enable_type_checks);
19 19
20 #define __ assembler-> 20 #define __ assembler->
21 21
22 22
23 void Intrinsifier::ObjectArrayLength(Assembler* assembler) { 23 intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
24 __ lw(V0, Address(SP, 0 * kWordSize));
25 __ Ret();
26 __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset()));
27 }
28
29
30 void Intrinsifier::ImmutableArrayLength(Assembler* assembler) {
31 ObjectArrayLength(assembler);
32 }
33
34
35 void Intrinsifier::ObjectArrayGetIndexed(Assembler* assembler) {
36 Label fall_through;
37
38 __ lw(T0, Address(SP, + 0 * kWordSize)); // Index
39
40 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
41 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through
42 __ delay_slot()->lw(T1, Address(SP, + 1 * kWordSize)); // Array
43
44 // Range check.
45 __ lw(T2, FieldAddress(T1, Array::length_offset()));
46 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
47
48 ASSERT(kSmiTagShift == 1);
49 // array element at T1 + T0*2 + Array::data_offset - 1
50 __ sll(T2, T0, 1);
51 __ addu(T2, T1, T2);
52 __ Ret();
53 __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset()));
54 __ Bind(&fall_through);
55 }
56
57
58 void Intrinsifier::ImmutableArrayGetIndexed(Assembler* assembler) {
59 ObjectArrayGetIndexed(assembler);
60 }
61 24
62 25
63 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 26 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
64 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 27 const Library& core_lib = Library::Handle(Library::CoreLibrary());
65 const Class& cls = Class::Handle( 28 const Class& cls = Class::Handle(
66 core_lib.LookupClassAllowPrivate(Symbols::_List())); 29 core_lib.LookupClassAllowPrivate(Symbols::_List()));
67 ASSERT(!cls.IsNull()); 30 ASSERT(!cls.IsNull());
68 ASSERT(cls.NumTypeArguments() == 1); 31 ASSERT(cls.NumTypeArguments() == 1);
69 const intptr_t field_offset = cls.type_arguments_field_offset(); 32 const intptr_t field_offset = cls.type_arguments_field_offset();
70 ASSERT(field_offset != Class::kNoTypeArguments); 33 ASSERT(field_offset != Class::kNoTypeArguments);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 T1); 125 T1);
163 // Set the length field in the growable array object to 0. 126 // Set the length field in the growable array object to 0.
164 __ Ret(); // Returns the newly allocated object in V0. 127 __ Ret(); // Returns the newly allocated object in V0.
165 __ delay_slot()->sw(ZR, 128 __ delay_slot()->sw(ZR,
166 FieldAddress(V0, GrowableObjectArray::length_offset())); 129 FieldAddress(V0, GrowableObjectArray::length_offset()));
167 130
168 __ Bind(&fall_through); 131 __ Bind(&fall_through);
169 } 132 }
170 133
171 134
172 void Intrinsifier::GrowableArrayLength(Assembler* assembler) {
173 __ lw(V0, Address(SP, 0 * kWordSize));
174 __ Ret();
175 __ delay_slot()->lw(V0,
176 FieldAddress(V0, GrowableObjectArray::length_offset()));
177 }
178
179
180 void Intrinsifier::GrowableArrayCapacity(Assembler* assembler) {
181 __ lw(V0, Address(SP, 0 * kWordSize));
182 __ lw(V0, FieldAddress(V0, GrowableObjectArray::data_offset()));
183 __ Ret();
184 __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset()));
185 }
186
187
188 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { 135 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) {
189 Label fall_through; 136 Label fall_through;
190 137
191 __ lw(T0, Address(SP, 0 * kWordSize)); // Index 138 __ lw(T0, Address(SP, 0 * kWordSize)); // Index
192 139
193 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); 140 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
194 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through 141 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through
195 __ delay_slot()->lw(T1, Address(SP, 1 * kWordSize)); // Array 142 __ delay_slot()->lw(T1, Address(SP, 1 * kWordSize)); // Array
196 143
197 // Range check. 144 // Range check.
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 __ BranchUnsignedGreaterEqual(T2, T1, &done); \ 338 __ BranchUnsignedGreaterEqual(T2, T1, &done); \
392 __ sw(ZR, Address(T2, 0)); \ 339 __ sw(ZR, Address(T2, 0)); \
393 __ b(&init_loop); \ 340 __ b(&init_loop); \
394 __ delay_slot()->addiu(T2, T2, Immediate(kWordSize)); \ 341 __ delay_slot()->addiu(T2, T2, Immediate(kWordSize)); \
395 __ Bind(&done); \ 342 __ Bind(&done); \
396 \ 343 \
397 __ Ret(); \ 344 __ Ret(); \
398 __ Bind(&fall_through); \ 345 __ Bind(&fall_through); \
399 346
400 347
401 // Gets the length of a TypedData.
402 void Intrinsifier::TypedDataLength(Assembler* assembler) {
403 __ lw(T0, Address(SP, 0 * kWordSize));
404 __ Ret();
405 __ delay_slot()->lw(V0, FieldAddress(T0, TypedData::length_offset()));
406 }
407
408
409 void Intrinsifier::Uint8ArrayGetIndexed(Assembler* assembler) {
410 Label fall_through;
411
412 __ lw(T0, Address(SP, + 0 * kWordSize)); // Index.
413
414 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
415 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through.
416 __ delay_slot()->lw(T1, Address(SP, + 1 * kWordSize)); // Array.
417
418 // Range check.
419 __ lw(T2, FieldAddress(T1, TypedData::length_offset()));
420 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
421
422 __ SmiUntag(T0);
423 __ addu(T1, T1, T0);
424 __ lbu(V0, FieldAddress(T1, TypedData::data_offset()));
425 __ Ret();
426 __ delay_slot()->SmiTag(V0);
427
428 __ Bind(&fall_through);
429 }
430
431
432 void Intrinsifier::ExternalUint8ArrayGetIndexed(Assembler* assembler) {
433 Label fall_through;
434
435 __ lw(T0, Address(SP, + 0 * kWordSize)); // Index.
436
437 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
438 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through.
439 __ delay_slot()->lw(T1, Address(SP, + 1 * kWordSize)); // Array.
440
441 // Range check.
442 __ lw(T2, FieldAddress(T1, TypedData::length_offset()));
443 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
444
445 __ lw(T1, FieldAddress(T1, ExternalTypedData::data_offset()));
446 __ SmiUntag(T0);
447 __ addu(T1, T1, T0);
448 __ lbu(V0, Address(T1, 0));
449 __ Ret();
450 __ delay_slot()->SmiTag(V0);
451
452 __ Bind(&fall_through);
453 }
454
455
456 void Intrinsifier::Float64ArrayGetIndexed(Assembler* assembler) {
457 Label fall_through;
458
459 __ lw(T0, Address(SP, + 0 * kWordSize)); // Index.
460
461 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
462 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through.
463 __ delay_slot()->lw(T1, Address(SP, + 1 * kWordSize)); // Array.
464
465 // Range check.
466 __ lw(T2, FieldAddress(T1, TypedData::length_offset()));
467 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
468
469 Address element_address =
470 __ ElementAddressForRegIndex(true, // Load.
471 false, // Not external.
472 kTypedDataFloat64ArrayCid, // Cid.
473 8, // Index scale.
474 T1, // Array.
475 T0); // Index.
476
477 __ LoadDFromOffset(D0, element_address.base(), element_address.offset());
478
479 const Class& double_class = Class::Handle(
480 Isolate::Current()->object_store()->double_class());
481 __ TryAllocate(double_class,
482 &fall_through,
483 V0, // Result register.
484 T1);
485 __ StoreDToOffset(D0, V0, Double::value_offset() - kHeapObjectTag);
486 __ Ret();
487 __ Bind(&fall_through);
488 }
489
490
491 void Intrinsifier::Float64ArraySetIndexed(Assembler* assembler) {
492 Label fall_through;
493
494 __ lw(T0, Address(SP, + 1 * kWordSize)); // Index.
495
496 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
497 __ bne(CMPRES1, ZR, &fall_through); // Index is not an smi, fall through.
498 __ delay_slot()->lw(T1, Address(SP, + 2 * kWordSize)); // Array.
499
500 // Range check.
501 __ lw(T2, FieldAddress(T1, TypedData::length_offset()));
502 __ BranchUnsignedGreaterEqual(T0, T2, &fall_through);
503
504 __ lw(T2, Address(SP, + 0 * kWordSize)); // Value.
505 __ andi(CMPRES1, T2, Immediate(kSmiTagMask));
506 __ beq(CMPRES1, ZR, &fall_through); // Value is a Smi. Fall through.
507
508 __ LoadClassId(T3, T2);
509 __ BranchNotEqual(T3, kDoubleCid, &fall_through); // Not a Double.
510
511 __ LoadDFromOffset(D0, T2, Double::value_offset() - kHeapObjectTag);
512
513 Address element_address =
514 __ ElementAddressForRegIndex(false, // Store.
515 false, // Not external.
516 kTypedDataFloat64ArrayCid, // Cid.
517 8, // Index scale.
518 T1, // Array.
519 T0); // Index.
520 __ StoreDToOffset(D0, element_address.base(), element_address.offset());
521 __ Ret();
522 __ Bind(&fall_through);
523 }
524
525
526 static int GetScaleFactor(intptr_t size) { 348 static int GetScaleFactor(intptr_t size) {
527 switch (size) { 349 switch (size) {
528 case 1: return 0; 350 case 1: return 0;
529 case 2: return 1; 351 case 2: return 1;
530 case 4: return 2; 352 case 4: return 2;
531 case 8: return 3; 353 case 8: return 3;
532 case 16: return 4; 354 case 16: return 4;
533 } 355 }
534 UNREACHABLE(); 356 UNREACHABLE();
535 return -1; 357 return -1;
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1220 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1399 Label fall_through; 1221 Label fall_through;
1400 __ lw(T0, Address(SP, 0 * kWordSize)); 1222 __ lw(T0, Address(SP, 0 * kWordSize));
1401 __ lw(V0, FieldAddress(T0, String::hash_offset())); 1223 __ lw(V0, FieldAddress(T0, String::hash_offset()));
1402 __ beq(V0, ZR, &fall_through); 1224 __ beq(V0, ZR, &fall_through);
1403 __ Ret(); 1225 __ Ret();
1404 __ Bind(&fall_through); // Hash not yet computed. 1226 __ Bind(&fall_through); // Hash not yet computed.
1405 } 1227 }
1406 1228
1407 1229
1408 void Intrinsifier::StringBaseLength(Assembler* assembler) {
1409 __ lw(T0, Address(SP, 0 * kWordSize));
1410 __ Ret();
1411 __ delay_slot()->lw(V0, FieldAddress(T0, String::length_offset()));
1412 }
1413
1414
1415 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) { 1230 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
1416 Label fall_through, try_two_byte_string; 1231 Label fall_through, try_two_byte_string;
1417 1232
1418 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1233 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1419 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1234 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1420 1235
1421 // Checks. 1236 // Checks.
1422 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1237 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1423 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1238 __ bne(T1, ZR, &fall_through); // Index is not a Smi.
1424 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1239 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 Isolate* isolate = Isolate::Current(); 1648 Isolate* isolate = Isolate::Current();
1834 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate)); 1649 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate));
1835 // Set return value. 1650 // Set return value.
1836 __ Ret(); 1651 __ Ret();
1837 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); 1652 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset()));
1838 } 1653 }
1839 1654
1840 } // namespace dart 1655 } // namespace dart
1841 1656
1842 #endif // defined TARGET_ARCH_MIPS 1657 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698