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

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

Issue 20369003: Implements far branch targets for MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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/vm/intermediate_language_mips.cc ('k') | runtime/vm/simulator_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/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 __ beq(T2, T7, &checked_ok); 206 __ beq(T2, T7, &checked_ok);
207 207
208 __ lw(T1, Address(SP, 2 * kWordSize)); // Array. 208 __ lw(T1, Address(SP, 2 * kWordSize)); // Array.
209 __ lw(T1, FieldAddress(T1, type_args_field_offset)); 209 __ lw(T1, FieldAddress(T1, type_args_field_offset));
210 210
211 // T1: Type arguments of array. 211 // T1: Type arguments of array.
212 __ beq(T1, T7, &checked_ok); 212 __ beq(T1, T7, &checked_ok);
213 213
214 // Check if it's dynamic. 214 // Check if it's dynamic.
215 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. 215 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
216 __ LoadClassId(TMP, T1); 216 __ LoadClassId(CMPRES1, T1);
217 __ BranchNotEqual(TMP, kTypeArgumentsCid, &fall_through); 217 __ BranchNotEqual(CMPRES1, kTypeArgumentsCid, &fall_through);
218 218
219 // Get type at index 0. 219 // Get type at index 0.
220 __ lw(T0, FieldAddress(T1, TypeArguments::type_at_offset(0))); 220 __ lw(T0, FieldAddress(T1, TypeArguments::type_at_offset(0)));
221 __ BranchEqual(T0, Type::ZoneHandle(Type::DynamicType()), &checked_ok); 221 __ BranchEqual(T0, Type::ZoneHandle(Type::DynamicType()), &checked_ok);
222 222
223 // Check for int and num. 223 // Check for int and num.
224 __ andi(CMPRES, T2, Immediate(kSmiTagMask)); 224 __ andi(CMPRES, T2, Immediate(kSmiTagMask));
225 __ bne(CMPRES, ZR, &fall_through); // Non-smi value. 225 __ bne(CMPRES, ZR, &fall_through); // Non-smi value.
226 226
227 __ BranchEqual(T0, Type::ZoneHandle(Type::IntType()), &checked_ok); 227 __ BranchEqual(T0, Type::ZoneHandle(Type::IntType()), &checked_ok);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 // On stack: growable array (+1), data (+0). 417 // On stack: growable array (+1), data (+0).
418 bool Intrinsifier::GrowableArray_setData(Assembler* assembler) { 418 bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
419 if (FLAG_enable_type_checks) { 419 if (FLAG_enable_type_checks) {
420 return false; 420 return false;
421 } 421 }
422 Label fall_through; 422 Label fall_through;
423 __ lw(T1, Address(SP, 0 * kWordSize)); // Data. 423 __ lw(T1, Address(SP, 0 * kWordSize)); // Data.
424 // Check that data is an ObjectArray. 424 // Check that data is an ObjectArray.
425 __ andi(CMPRES, T1, Immediate(kSmiTagMask)); 425 __ andi(CMPRES, T1, Immediate(kSmiTagMask));
426 __ beq(CMPRES, ZR, &fall_through); // Data is Smi. 426 __ beq(CMPRES, ZR, &fall_through); // Data is Smi.
427 __ LoadClassId(TMP, T1); 427 __ LoadClassId(CMPRES1, T1);
428 __ BranchNotEqual(TMP, kArrayCid, &fall_through); 428 __ BranchNotEqual(CMPRES1, kArrayCid, &fall_through);
429 __ lw(T0, Address(SP, 1 * kWordSize)); // Growable array. 429 __ lw(T0, Address(SP, 1 * kWordSize)); // Growable array.
430 __ StoreIntoObject(T0, 430 __ StoreIntoObject(T0,
431 FieldAddress(T0, GrowableObjectArray::data_offset()), 431 FieldAddress(T0, GrowableObjectArray::data_offset()),
432 T1); 432 T1);
433 __ Ret(); 433 __ Ret();
434 __ Bind(&fall_through); 434 __ Bind(&fall_through);
435 return false; 435 return false;
436 } 436 }
437 437
438 438
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 ASSERT(kSmiTag == 0); 858 ASSERT(kSmiTag == 0);
859 Label fall_through, overflow; 859 Label fall_through, overflow;
860 860
861 TestBothArgumentsSmis(assembler, &fall_through); 861 TestBothArgumentsSmis(assembler, &fall_through);
862 __ BranchUnsignedGreater(T0, Smi::RawValue(Smi::kBits), &fall_through); 862 __ BranchUnsignedGreater(T0, Smi::RawValue(Smi::kBits), &fall_through);
863 __ SmiUntag(T0); 863 __ SmiUntag(T0);
864 864
865 // Check for overflow by shifting left and shifting back arithmetically. 865 // Check for overflow by shifting left and shifting back arithmetically.
866 // If the result is different from the original, there was overflow. 866 // If the result is different from the original, there was overflow.
867 __ sllv(TMP, T1, T0); 867 __ sllv(TMP, T1, T0);
868 __ srav(TMP, TMP, T0); 868 __ srav(CMPRES1, TMP, T0);
869 __ bne(TMP, T1, &overflow); 869 __ bne(CMPRES1, T1, &overflow);
870 870
871 // No overflow, result in V0. 871 // No overflow, result in V0.
872 __ Ret(); 872 __ Ret();
873 __ delay_slot()->sllv(V0, T1, T0); 873 __ delay_slot()->sllv(V0, T1, T0);
874 874
875 __ Bind(&overflow); 875 __ Bind(&overflow);
876 // Arguments are Smi but the shift produced an overflow to Mint. 876 // Arguments are Smi but the shift produced an overflow to Mint.
877 __ bltz(T1, &fall_through); 877 __ bltz(T1, &fall_through);
878 __ SmiUntag(T1); 878 __ SmiUntag(T1);
879 879
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 __ andi(CMPRES, reg, Immediate(kSmiTagMask)); 913 __ andi(CMPRES, reg, Immediate(kSmiTagMask));
914 __ bne(CMPRES, ZR, &not_smi); 914 __ bne(CMPRES, ZR, &not_smi);
915 __ SmiUntag(reg); 915 __ SmiUntag(reg);
916 916
917 // Sign extend to 64 bit 917 // Sign extend to 64 bit
918 __ mov(res_lo, reg); 918 __ mov(res_lo, reg);
919 __ b(&done); 919 __ b(&done);
920 __ delay_slot()->sra(res_hi, reg, 31); 920 __ delay_slot()->sra(res_hi, reg, 31);
921 921
922 __ Bind(&not_smi); 922 __ Bind(&not_smi);
923 __ LoadClassId(TMP, reg); 923 __ LoadClassId(CMPRES1, reg);
924 __ BranchNotEqual(TMP, kMintCid, not_smi_or_mint); 924 __ BranchNotEqual(CMPRES1, kMintCid, not_smi_or_mint);
925 925
926 // Mint. 926 // Mint.
927 __ lw(res_lo, FieldAddress(reg, Mint::value_offset())); 927 __ lw(res_lo, FieldAddress(reg, Mint::value_offset()));
928 __ lw(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize)); 928 __ lw(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize));
929 __ Bind(&done); 929 __ Bind(&done);
930 return; 930 return;
931 } 931 }
932 932
933 933
934 static bool CompareIntegers(Assembler* assembler, Condition true_condition) { 934 static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 Label receiver_not_smi; 1054 Label receiver_not_smi;
1055 __ Bind(&check_for_mint); 1055 __ Bind(&check_for_mint);
1056 1056
1057 __ andi(CMPRES, T1, Immediate(kSmiTagMask)); 1057 __ andi(CMPRES, T1, Immediate(kSmiTagMask));
1058 __ bne(CMPRES, ZR, &receiver_not_smi); // Check receiver. 1058 __ bne(CMPRES, ZR, &receiver_not_smi); // Check receiver.
1059 1059
1060 // Left (receiver) is Smi, return false if right is not Double. 1060 // Left (receiver) is Smi, return false if right is not Double.
1061 // Note that an instance of Mint or Bigint never contains a value that can be 1061 // Note that an instance of Mint or Bigint never contains a value that can be
1062 // represented by Smi. 1062 // represented by Smi.
1063 1063
1064 __ LoadClassId(TMP, T0); 1064 __ LoadClassId(CMPRES1, T0);
1065 __ BranchEqual(TMP, kDoubleCid, &fall_through); 1065 __ BranchEqual(CMPRES1, kDoubleCid, &fall_through);
1066 __ LoadObject(V0, Bool::False()); // Smi == Mint -> false. 1066 __ LoadObject(V0, Bool::False()); // Smi == Mint -> false.
1067 __ Ret(); 1067 __ Ret();
1068 1068
1069 __ Bind(&receiver_not_smi); 1069 __ Bind(&receiver_not_smi);
1070 // T1:: receiver. 1070 // T1:: receiver.
1071 1071
1072 __ LoadClassId(TMP, T1); 1072 __ LoadClassId(CMPRES1, T1);
1073 __ BranchNotEqual(TMP, kMintCid, &fall_through); 1073 __ BranchNotEqual(CMPRES1, kMintCid, &fall_through);
1074 // Receiver is Mint, return false if right is Smi. 1074 // Receiver is Mint, return false if right is Smi.
1075 __ andi(CMPRES, T0, Immediate(kSmiTagMask)); 1075 __ andi(CMPRES, T0, Immediate(kSmiTagMask));
1076 __ bne(CMPRES, ZR, &fall_through); 1076 __ bne(CMPRES, ZR, &fall_through);
1077 __ LoadObject(V0, Bool::False()); 1077 __ LoadObject(V0, Bool::False());
1078 __ Ret(); 1078 __ Ret();
1079 // TODO(srdjan): Implement Mint == Mint comparison. 1079 // TODO(srdjan): Implement Mint == Mint comparison.
1080 1080
1081 __ Bind(&fall_through); 1081 __ Bind(&fall_through);
1082 return false; 1082 return false;
1083 } 1083 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 1121
1122 // Check if the last argument is a double, jump to label 'is_smi' if smi 1122 // Check if the last argument is a double, jump to label 'is_smi' if smi
1123 // (easy to convert to double), otherwise jump to label 'not_double_smi', 1123 // (easy to convert to double), otherwise jump to label 'not_double_smi',
1124 // Returns the last argument in T0. 1124 // Returns the last argument in T0.
1125 static void TestLastArgumentIsDouble(Assembler* assembler, 1125 static void TestLastArgumentIsDouble(Assembler* assembler,
1126 Label* is_smi, 1126 Label* is_smi,
1127 Label* not_double_smi) { 1127 Label* not_double_smi) {
1128 __ lw(T0, Address(SP, 0 * kWordSize)); 1128 __ lw(T0, Address(SP, 0 * kWordSize));
1129 __ andi(CMPRES, T0, Immediate(kSmiTagMask)); 1129 __ andi(CMPRES, T0, Immediate(kSmiTagMask));
1130 __ beq(CMPRES, ZR, is_smi); 1130 __ beq(CMPRES, ZR, is_smi);
1131 __ LoadClassId(TMP, T0); 1131 __ LoadClassId(CMPRES1, T0);
1132 __ BranchNotEqual(TMP, kDoubleCid, not_double_smi); 1132 __ BranchNotEqual(CMPRES1, kDoubleCid, not_double_smi);
1133 // Fall through with Double in T0. 1133 // Fall through with Double in T0.
1134 } 1134 }
1135 1135
1136 1136
1137 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown 1137 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
1138 // type. Return true or false object in the register V0. Any NaN argument 1138 // type. Return true or false object in the register V0. Any NaN argument
1139 // returns false. Any non-double arg1 causes control flow to fall through to the 1139 // returns false. Any non-double arg1 causes control flow to fall through to the
1140 // slow case (compiled method body). 1140 // slow case (compiled method body).
1141 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { 1141 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
1142 Label is_smi, double_op, no_NaN, fall_through; 1142 Label is_smi, double_op, no_NaN, fall_through;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 1511
1512 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1512 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1513 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1513 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1514 1514
1515 // Checks. 1515 // Checks.
1516 __ andi(CMPRES, T1, Immediate(kSmiTagMask)); 1516 __ andi(CMPRES, T1, Immediate(kSmiTagMask));
1517 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1517 __ bne(T1, ZR, &fall_through); // Index is not a Smi.
1518 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1518 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
1519 // Runtime throws exception. 1519 // Runtime throws exception.
1520 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 1520 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
1521 __ LoadClassId(TMP1, T0); // Class ID check. 1521 __ LoadClassId(CMPRES1, T0); // Class ID check.
1522 __ BranchNotEqual(TMP1, kOneByteStringCid, &try_two_byte_string); 1522 __ BranchNotEqual(CMPRES1, kOneByteStringCid, &try_two_byte_string);
1523 1523
1524 // Grab byte and return. 1524 // Grab byte and return.
1525 __ SmiUntag(T1); 1525 __ SmiUntag(T1);
1526 __ addu(T2, T0, T1); 1526 __ addu(T2, T0, T1);
1527 __ lbu(V0, FieldAddress(T2, OneByteString::data_offset())); 1527 __ lbu(V0, FieldAddress(T2, OneByteString::data_offset()));
1528 __ Ret(); 1528 __ Ret();
1529 __ delay_slot()->SmiTag(V0); 1529 __ delay_slot()->SmiTag(V0);
1530 1530
1531 __ Bind(&try_two_byte_string); 1531 __ Bind(&try_two_byte_string);
1532 __ BranchNotEqual(TMP1, kTwoByteStringCid, &fall_through); 1532 __ BranchNotEqual(CMPRES1, kTwoByteStringCid, &fall_through);
1533 ASSERT(kSmiTagShift == 1); 1533 ASSERT(kSmiTagShift == 1);
1534 __ addu(T2, T0, T1); 1534 __ addu(T2, T0, T1);
1535 __ lhu(V0, FieldAddress(T2, OneByteString::data_offset())); 1535 __ lhu(V0, FieldAddress(T2, OneByteString::data_offset()));
1536 __ Ret(); 1536 __ Ret();
1537 __ delay_slot()->SmiTag(V0); 1537 __ delay_slot()->SmiTag(V0);
1538 1538
1539 __ Bind(&fall_through); 1539 __ Bind(&fall_through);
1540 return false; 1540 return false;
1541 } 1541 }
1542 1542
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 // Add to hash code: (hash_ is uint32) 1586 // Add to hash code: (hash_ is uint32)
1587 // hash_ += ch; 1587 // hash_ += ch;
1588 // hash_ += hash_ << 10; 1588 // hash_ += hash_ << 10;
1589 // hash_ ^= hash_ >> 6; 1589 // hash_ ^= hash_ >> 6;
1590 // Get one characters (ch). 1590 // Get one characters (ch).
1591 __ Bind(&loop); 1591 __ Bind(&loop);
1592 __ lbu(T5, Address(T3)); 1592 __ lbu(T5, Address(T3));
1593 // T5: ch. 1593 // T5: ch.
1594 __ addiu(T3, T3, Immediate(1)); 1594 __ addiu(T3, T3, Immediate(1));
1595 __ addu(V0, V0, T5); 1595 __ addu(V0, V0, T5);
1596 __ sll(TMP, V0, 10); 1596 __ sll(T6, V0, 10);
1597 __ addu(V0, V0, TMP); 1597 __ addu(V0, V0, T6);
1598 __ srl(TMP, V0, 6); 1598 __ srl(T6, V0, 6);
1599 __ bne(T3, T4, &loop); 1599 __ bne(T3, T4, &loop);
1600 __ delay_slot()->xor_(V0, V0, TMP); 1600 __ delay_slot()->xor_(V0, V0, T6);
1601 1601
1602 // Finalize. 1602 // Finalize.
1603 // hash_ += hash_ << 3; 1603 // hash_ += hash_ << 3;
1604 // hash_ ^= hash_ >> 11; 1604 // hash_ ^= hash_ >> 11;
1605 // hash_ += hash_ << 15; 1605 // hash_ += hash_ << 15;
1606 __ sll(TMP, V0, 3); 1606 __ sll(T6, V0, 3);
1607 __ addu(V0, V0, TMP); 1607 __ addu(V0, V0, T6);
1608 __ srl(TMP, V0, 11); 1608 __ srl(T6, V0, 11);
1609 __ xor_(V0, V0, TMP); 1609 __ xor_(V0, V0, T6);
1610 __ sll(TMP, V0, 15); 1610 __ sll(T6, V0, 15);
1611 __ addu(V0, V0, TMP); 1611 __ addu(V0, V0, T6);
1612 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); 1612 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
1613 __ LoadImmediate(TMP, (static_cast<intptr_t>(1) << String::kHashBits) - 1); 1613 __ LoadImmediate(T6, (static_cast<intptr_t>(1) << String::kHashBits) - 1);
1614 __ and_(V0, V0, TMP); 1614 __ and_(V0, V0, T6);
1615 __ Bind(&done); 1615 __ Bind(&done);
1616 1616
1617 __ LoadImmediate(T2, 1); 1617 __ LoadImmediate(T2, 1);
1618 __ movz(V0, T2, V0); // If V0 is 0, set to 1. 1618 __ movz(V0, T2, V0); // If V0 is 0, set to 1.
1619 __ SmiTag(V0); 1619 __ SmiTag(V0);
1620 1620
1621 __ Ret(); 1621 __ Ret();
1622 __ delay_slot()->sw(V0, FieldAddress(T1, String::hash_offset())); 1622 __ delay_slot()->sw(V0, FieldAddress(T1, String::hash_offset()));
1623 return true; 1623 return true;
1624 } 1624 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 __ Bind(&ok); 1775 __ Bind(&ok);
1776 __ Ret(); 1776 __ Ret();
1777 1777
1778 __ Bind(&fall_through); 1778 __ Bind(&fall_through);
1779 return false; 1779 return false;
1780 } 1780 }
1781 1781
1782 } // namespace dart 1782 } // namespace dart
1783 1783
1784 #endif // defined TARGET_ARCH_MIPS 1784 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/simulator_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698