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

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

Issue 1043943002: A few fixes for ARMv5TE. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 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/vm/intermediate_language_arm.cc ('k') | runtime/vm/object_test.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_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/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 /* R4: allocation stats address */ \ 254 /* R4: allocation stats address */ \
255 /* R6, R7: zero. */ \ 255 /* R6, R7: zero. */ \
256 /* data area to be initialized. */ \ 256 /* data area to be initialized. */ \
257 __ LoadImmediate(R6, 0); \ 257 __ LoadImmediate(R6, 0); \
258 __ mov(R7, Operand(R6)); \ 258 __ mov(R7, Operand(R6)); \
259 __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1); \ 259 __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1); \
260 Label init_loop; \ 260 Label init_loop; \
261 __ Bind(&init_loop); \ 261 __ Bind(&init_loop); \
262 __ AddImmediate(R3, 2 * kWordSize); \ 262 __ AddImmediate(R3, 2 * kWordSize); \
263 __ cmp(R3, Operand(R1)); \ 263 __ cmp(R3, Operand(R1)); \
264 __ strd(R6, Address(R3, -2 * kWordSize), LS); \ 264 __ strd(R6, R3, -2 * kWordSize, LS); \
265 __ b(&init_loop, CC); \ 265 __ b(&init_loop, CC); \
266 __ str(R6, Address(R3, -2 * kWordSize), HI); \ 266 __ str(R6, Address(R3, -2 * kWordSize), HI); \
267 \ 267 \
268 __ IncrementAllocationStatsWithSize(R4, R2, cid, space); \ 268 __ IncrementAllocationStatsWithSize(R4, R2, cid, space); \
269 __ Ret(); \ 269 __ Ret(); \
270 __ Bind(&fall_through); \ 270 __ Bind(&fall_through); \
271 271
272 272
273 static int GetScaleFactor(intptr_t size) { 273 static int GetScaleFactor(intptr_t size) {
274 switch (size) { 274 switch (size) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 Label fall_through; 341 Label fall_through;
342 TestBothArgumentsSmis(assembler, &fall_through); 342 TestBothArgumentsSmis(assembler, &fall_through);
343 __ subs(R0, R1, Operand(R0)); // Subtract. 343 __ subs(R0, R1, Operand(R0)); // Subtract.
344 __ bx(LR, VC); // Return if no overflow. 344 __ bx(LR, VC); // Return if no overflow.
345 // Otherwise fall through. 345 // Otherwise fall through.
346 __ Bind(&fall_through); 346 __ Bind(&fall_through);
347 } 347 }
348 348
349 349
350 void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) { 350 void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
351 if (TargetCPUFeatures::arm_version() == ARMv7) { 351 Label fall_through;
352 Label fall_through; 352 TestBothArgumentsSmis(assembler, &fall_through); // checks two smis
353 TestBothArgumentsSmis(assembler, &fall_through); // checks two smis 353 __ SmiUntag(R0); // Untags R6. We only want result shifted by one.
354 __ SmiUntag(R0); // Untags R6. We only want result shifted by one. 354 __ smull(R0, IP, R0, R1); // IP:R0 <- R0 * R1.
355 __ smull(R0, IP, R0, R1); // IP:R0 <- R0 * R1. 355 __ cmp(IP, Operand(R0, ASR, 31));
356 __ cmp(IP, Operand(R0, ASR, 31)); 356 __ bx(LR, EQ);
357 __ bx(LR, EQ); 357 __ Bind(&fall_through); // Fall through on overflow.
358 __ Bind(&fall_through); // Fall through on overflow.
359 } else if (TargetCPUFeatures::can_divide()) {
360 Label fall_through;
361 TestBothArgumentsSmis(assembler, &fall_through); // checks two smis
362 __ SmiUntag(R0); // Untags R6. We only want result shifted by one.
363 __ CheckMultSignedOverflow(R0, R1, IP, D0, D1, &fall_through);
364 __ mul(R0, R0, R1);
365 __ Ret();
366 __ Bind(&fall_through); // Fall through on overflow.
367 }
368 } 358 }
369 359
370 360
371 void Intrinsifier::Integer_mul(Assembler* assembler) { 361 void Intrinsifier::Integer_mul(Assembler* assembler) {
372 Integer_mulFromInteger(assembler); 362 Integer_mulFromInteger(assembler);
373 } 363 }
374 364
375 365
376 // Optimizations: 366 // Optimizations:
377 // - result is 0 if: 367 // - result is 0 if:
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 // TODO(sra): Implement as word-length - CLZ. 789 // TODO(sra): Implement as word-length - CLZ.
800 } 790 }
801 791
802 792
803 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { 793 void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
804 // static void _absAdd(Uint32List digits, int used, 794 // static void _absAdd(Uint32List digits, int used,
805 // Uint32List a_digits, int a_used, 795 // Uint32List a_digits, int a_used,
806 // Uint32List r_digits) 796 // Uint32List r_digits)
807 797
808 // R2 = used, R3 = digits 798 // R2 = used, R3 = digits
809 __ ldrd(R2, Address(SP, 3 * kWordSize)); 799 __ ldrd(R2, SP, 3 * kWordSize);
810 // R3 = &digits[0] 800 // R3 = &digits[0]
811 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 801 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
812 802
813 // R4 = a_used, R5 = a_digits 803 // R4 = a_used, R5 = a_digits
814 __ ldrd(R4, Address(SP, 1 * kWordSize)); 804 __ ldrd(R4, SP, 1 * kWordSize);
815 // R5 = &a_digits[0] 805 // R5 = &a_digits[0]
816 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); 806 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
817 807
818 // R6 = r_digits 808 // R6 = r_digits
819 __ ldr(R6, Address(SP, 0 * kWordSize)); 809 __ ldr(R6, Address(SP, 0 * kWordSize));
820 // R6 = &r_digits[0] 810 // R6 = &r_digits[0]
821 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); 811 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
822 812
823 // R7 = &digits[a_used >> 1], a_used is Smi. 813 // R7 = &digits[a_used >> 1], a_used is Smi.
824 __ add(R7, R3, Operand(R4, LSL, 1)); 814 __ add(R7, R3, Operand(R4, LSL, 1));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 __ Ret(); 849 __ Ret();
860 } 850 }
861 851
862 852
863 void Intrinsifier::Bigint_absSub(Assembler* assembler) { 853 void Intrinsifier::Bigint_absSub(Assembler* assembler) {
864 // static void _absSub(Uint32List digits, int used, 854 // static void _absSub(Uint32List digits, int used,
865 // Uint32List a_digits, int a_used, 855 // Uint32List a_digits, int a_used,
866 // Uint32List r_digits) 856 // Uint32List r_digits)
867 857
868 // R2 = used, R3 = digits 858 // R2 = used, R3 = digits
869 __ ldrd(R2, Address(SP, 3 * kWordSize)); 859 __ ldrd(R2, SP, 3 * kWordSize);
870 // R3 = &digits[0] 860 // R3 = &digits[0]
871 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 861 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
872 862
873 // R4 = a_used, R5 = a_digits 863 // R4 = a_used, R5 = a_digits
874 __ ldrd(R4, Address(SP, 1 * kWordSize)); 864 __ ldrd(R4, SP, 1 * kWordSize);
875 // R5 = &a_digits[0] 865 // R5 = &a_digits[0]
876 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); 866 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
877 867
878 // R6 = r_digits 868 // R6 = r_digits
879 __ ldr(R6, Address(SP, 0 * kWordSize)); 869 __ ldr(R6, Address(SP, 0 * kWordSize));
880 // R6 = &r_digits[0] 870 // R6 = &r_digits[0]
881 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); 871 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
882 872
883 // R7 = &digits[a_used >> 1], a_used is Smi. 873 // R7 = &digits[a_used >> 1], a_used is Smi.
884 __ add(R7, R3, Operand(R4, LSL, 1)); 874 __ add(R7, R3, Operand(R4, LSL, 1));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 // while (c != 0) { 932 // while (c != 0) {
943 // uint64_t t = *ajp + c; 933 // uint64_t t = *ajp + c;
944 // *ajp++ = low32(t); 934 // *ajp++ = low32(t);
945 // c = high32(t); // c == 0 or 1. 935 // c = high32(t); // c == 0 or 1.
946 // } 936 // }
947 // return 1; 937 // return 1;
948 // } 938 // }
949 939
950 Label done; 940 Label done;
951 // R3 = x, no_op if x == 0 941 // R3 = x, no_op if x == 0
952 __ ldrd(R0, Address(SP, 5 * kWordSize)); // R0 = xi as Smi, R1 = x_digits. 942 __ ldrd(R0, SP, 5 * kWordSize); // R0 = xi as Smi, R1 = x_digits.
953 __ add(R1, R1, Operand(R0, LSL, 1)); 943 __ add(R1, R1, Operand(R0, LSL, 1));
954 __ ldr(R3, FieldAddress(R1, TypedData::data_offset())); 944 __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
955 __ tst(R3, Operand(R3)); 945 __ tst(R3, Operand(R3));
956 __ b(&done, EQ); 946 __ b(&done, EQ);
957 947
958 // R6 = SmiUntag(n), no_op if n == 0 948 // R6 = SmiUntag(n), no_op if n == 0
959 __ ldr(R6, Address(SP, 0 * kWordSize)); 949 __ ldr(R6, Address(SP, 0 * kWordSize));
960 __ Asrs(R6, R6, Operand(kSmiTagSize)); 950 __ Asrs(R6, R6, Operand(kSmiTagSize));
961 __ b(&done, EQ); 951 __ b(&done, EQ);
962 952
963 // R4 = mip = &m_digits[i >> 1] 953 // R4 = mip = &m_digits[i >> 1]
964 __ ldrd(R0, Address(SP, 3 * kWordSize)); // R0 = i as Smi, R1 = m_digits. 954 __ ldrd(R0, SP, 3 * kWordSize); // R0 = i as Smi, R1 = m_digits.
965 __ add(R1, R1, Operand(R0, LSL, 1)); 955 __ add(R1, R1, Operand(R0, LSL, 1));
966 __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag)); 956 __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
967 957
968 // R5 = ajp = &a_digits[j >> 1] 958 // R5 = ajp = &a_digits[j >> 1]
969 __ ldrd(R0, Address(SP, 1 * kWordSize)); // R0 = j as Smi, R1 = a_digits. 959 __ ldrd(R0, SP, 1 * kWordSize); // R0 = j as Smi, R1 = a_digits.
970 __ add(R1, R1, Operand(R0, LSL, 1)); 960 __ add(R1, R1, Operand(R0, LSL, 1));
971 __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag)); 961 __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
972 962
973 // R1 = c = 0 963 // R1 = c = 0
974 __ mov(R1, Operand(0)); 964 __ mov(R1, Operand(0));
975 965
976 Label muladd_loop; 966 Label muladd_loop;
977 __ Bind(&muladd_loop); 967 __ Bind(&muladd_loop);
978 // x: R3 968 // x: R3
979 // mip: R4 969 // mip: R4
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 // c = high64(t); // 33-bit. 1035 // c = high64(t); // 33-bit.
1046 // } 1036 // }
1047 // uint32_t aj = *ajp; 1037 // uint32_t aj = *ajp;
1048 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit. 1038 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit.
1049 // *ajp++ = low32(t); 1039 // *ajp++ = low32(t);
1050 // *ajp = high32(t); 1040 // *ajp = high32(t);
1051 // return 1; 1041 // return 1;
1052 // } 1042 // }
1053 1043
1054 // R4 = xip = &x_digits[i >> 1] 1044 // R4 = xip = &x_digits[i >> 1]
1055 __ ldrd(R2, Address(SP, 2 * kWordSize)); // R2 = i as Smi, R3 = x_digits 1045 __ ldrd(R2, SP, 2 * kWordSize); // R2 = i as Smi, R3 = x_digits
1056 __ add(R3, R3, Operand(R2, LSL, 1)); 1046 __ add(R3, R3, Operand(R2, LSL, 1));
1057 __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 1047 __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
1058 1048
1059 // R3 = x = *xip++, return if x == 0 1049 // R3 = x = *xip++, return if x == 0
1060 Label x_zero; 1050 Label x_zero;
1061 __ ldr(R3, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex)); 1051 __ ldr(R3, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
1062 __ tst(R3, Operand(R3)); 1052 __ tst(R3, Operand(R3));
1063 __ b(&x_zero, EQ); 1053 __ b(&x_zero, EQ);
1064 1054
1065 // R5 = ajp = &a_digits[i] 1055 // R5 = ajp = &a_digits[i]
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 __ Bind(&done); 1113 __ Bind(&done);
1124 // uint32_t aj = *ajp 1114 // uint32_t aj = *ajp
1125 __ ldr(R0, Address(R5, 0)); 1115 __ ldr(R0, Address(R5, 0));
1126 1116
1127 // uint64_t t = aj + c 1117 // uint64_t t = aj + c
1128 __ adds(R6, R6, Operand(R0)); 1118 __ adds(R6, R6, Operand(R0));
1129 __ adc(R7, R7, Operand(0)); 1119 __ adc(R7, R7, Operand(0));
1130 1120
1131 // *ajp = low32(t) = R6 1121 // *ajp = low32(t) = R6
1132 // *(ajp + 1) = high32(t) = R7 1122 // *(ajp + 1) = high32(t) = R7
1133 __ strd(R6, Address(R5, 0)); 1123 __ strd(R6, R5, 0);
1134 1124
1135 __ Bind(&x_zero); 1125 __ Bind(&x_zero);
1136 __ mov(R0, Operand(Smi::RawValue(1))); // One digit processed. 1126 __ mov(R0, Operand(Smi::RawValue(1))); // One digit processed.
1137 __ Ret(); 1127 __ Ret();
1138 } 1128 }
1139 1129
1140 1130
1141 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1131 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
1142 // No unsigned 64-bit / 32-bit divide instruction. 1132 // No unsigned 64-bit / 32-bit divide instruction.
1143 } 1133 }
(...skipping 13 matching lines...) Expand all
1157 // } 1147 // }
1158 1148
1159 // R4 = args 1149 // R4 = args
1160 __ ldr(R4, Address(SP, 2 * kWordSize)); // args 1150 __ ldr(R4, Address(SP, 2 * kWordSize)); // args
1161 1151
1162 // R3 = rho = args[2] 1152 // R3 = rho = args[2]
1163 __ ldr(R3, FieldAddress(R4, 1153 __ ldr(R3, FieldAddress(R4,
1164 TypedData::data_offset() + 2*Bigint::kBytesPerDigit)); 1154 TypedData::data_offset() + 2*Bigint::kBytesPerDigit));
1165 1155
1166 // R2 = digits[i >> 1] 1156 // R2 = digits[i >> 1]
1167 __ ldrd(R0, Address(SP, 0 * kWordSize)); // R0 = i as Smi, R1 = digits 1157 __ ldrd(R0, SP, 0 * kWordSize); // R0 = i as Smi, R1 = digits
1168 __ add(R1, R1, Operand(R0, LSL, 1)); 1158 __ add(R1, R1, Operand(R0, LSL, 1));
1169 __ ldr(R2, FieldAddress(R1, TypedData::data_offset())); 1159 __ ldr(R2, FieldAddress(R1, TypedData::data_offset()));
1170 1160
1171 // R1:R0 = t = rho*d 1161 // R1:R0 = t = rho*d
1172 __ umull(R0, R1, R2, R3); 1162 __ umull(R0, R1, R2, R3);
1173 1163
1174 // args[4] = t mod DIGIT_BASE = low32(t) 1164 // args[4] = t mod DIGIT_BASE = low32(t)
1175 __ str(R0, 1165 __ str(R0,
1176 FieldAddress(R4, TypedData::data_offset() + 4*Bigint::kBytesPerDigit)); 1166 FieldAddress(R4, TypedData::data_offset() + 4*Bigint::kBytesPerDigit));
1177 1167
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 Isolate* isolate = Isolate::Current(); 1944 Isolate* isolate = Isolate::Current();
1955 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); 1945 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate));
1956 // Set return value to Isolate::current_tag_. 1946 // Set return value to Isolate::current_tag_.
1957 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); 1947 __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
1958 __ Ret(); 1948 __ Ret();
1959 } 1949 }
1960 1950
1961 } // namespace dart 1951 } // namespace dart
1962 1952
1963 #endif // defined TARGET_ARCH_ARM 1953 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698