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

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

Issue 1407393006: Make arm assembler explicitly take both registers for load/store-pair. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « runtime/vm/assembler_arm_test.cc ('k') | no next file » | 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 /* R4: allocation stats address */ \ 218 /* R4: allocation stats address */ \
219 /* R6, R7: zero. */ \ 219 /* R6, R7: zero. */ \
220 /* data area to be initialized. */ \ 220 /* data area to be initialized. */ \
221 __ LoadImmediate(R6, 0); \ 221 __ LoadImmediate(R6, 0); \
222 __ mov(R7, Operand(R6)); \ 222 __ mov(R7, Operand(R6)); \
223 __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1); \ 223 __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1); \
224 Label init_loop; \ 224 Label init_loop; \
225 __ Bind(&init_loop); \ 225 __ Bind(&init_loop); \
226 __ AddImmediate(R3, 2 * kWordSize); \ 226 __ AddImmediate(R3, 2 * kWordSize); \
227 __ cmp(R3, Operand(R1)); \ 227 __ cmp(R3, Operand(R1)); \
228 __ strd(R6, R3, -2 * kWordSize, LS); \ 228 __ strd(R6, R7, R3, -2 * kWordSize, LS); \
229 __ b(&init_loop, CC); \ 229 __ b(&init_loop, CC); \
230 __ str(R6, Address(R3, -2 * kWordSize), HI); \ 230 __ str(R6, Address(R3, -2 * kWordSize), HI); \
231 \ 231 \
232 __ IncrementAllocationStatsWithSize(R4, R2, space); \ 232 __ IncrementAllocationStatsWithSize(R4, R2, space); \
233 __ Ret(); \ 233 __ Ret(); \
234 __ Bind(&fall_through); \ 234 __ Bind(&fall_through); \
235 235
236 236
237 static int GetScaleFactor(intptr_t size) { 237 static int GetScaleFactor(intptr_t size) {
238 switch (size) { 238 switch (size) {
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 __ SmiTag(R0); 762 __ SmiTag(R0);
763 __ Ret(); 763 __ Ret();
764 } 764 }
765 765
766 766
767 void Intrinsifier::Bigint_lsh(Assembler* assembler) { 767 void Intrinsifier::Bigint_lsh(Assembler* assembler) {
768 // static void _lsh(Uint32List x_digits, int x_used, int n, 768 // static void _lsh(Uint32List x_digits, int x_used, int n,
769 // Uint32List r_digits) 769 // Uint32List r_digits)
770 770
771 // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi. 771 // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
772 __ ldrd(R2, SP, 2 * kWordSize); 772 __ ldrd(R2, R3, SP, 2 * kWordSize);
773 // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0. 773 // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
774 __ ldrd(R4, SP, 0 * kWordSize); 774 __ ldrd(R4, R5, SP, 0 * kWordSize);
775 __ SmiUntag(R5); 775 __ SmiUntag(R5);
776 // R0 = n ~/ _DIGIT_BITS 776 // R0 = n ~/ _DIGIT_BITS
777 __ Asr(R0, R5, Operand(5)); 777 __ Asr(R0, R5, Operand(5));
778 // R6 = &x_digits[0] 778 // R6 = &x_digits[0]
779 __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 779 __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
780 // R7 = &x_digits[x_used] 780 // R7 = &x_digits[x_used]
781 __ add(R7, R6, Operand(R2, LSL, 1)); 781 __ add(R7, R6, Operand(R2, LSL, 1));
782 // R10 = &r_digits[1] 782 // R10 = &r_digits[1]
783 __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag + 783 __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag +
784 Bigint::kBytesPerDigit)); 784 Bigint::kBytesPerDigit));
(...skipping 17 matching lines...) Expand all
802 // Returning Object::null() is not required, since this method is private. 802 // Returning Object::null() is not required, since this method is private.
803 __ Ret(); 803 __ Ret();
804 } 804 }
805 805
806 806
807 void Intrinsifier::Bigint_rsh(Assembler* assembler) { 807 void Intrinsifier::Bigint_rsh(Assembler* assembler) {
808 // static void _lsh(Uint32List x_digits, int x_used, int n, 808 // static void _lsh(Uint32List x_digits, int x_used, int n,
809 // Uint32List r_digits) 809 // Uint32List r_digits)
810 810
811 // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi. 811 // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
812 __ ldrd(R2, SP, 2 * kWordSize); 812 __ ldrd(R2, R3, SP, 2 * kWordSize);
813 // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0. 813 // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
814 __ ldrd(R4, SP, 0 * kWordSize); 814 __ ldrd(R4, R5, SP, 0 * kWordSize);
815 __ SmiUntag(R5); 815 __ SmiUntag(R5);
816 // R0 = n ~/ _DIGIT_BITS 816 // R0 = n ~/ _DIGIT_BITS
817 __ Asr(R0, R5, Operand(5)); 817 __ Asr(R0, R5, Operand(5));
818 // R10 = &r_digits[0] 818 // R10 = &r_digits[0]
819 __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag)); 819 __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag));
820 // R7 = &x_digits[n ~/ _DIGIT_BITS] 820 // R7 = &x_digits[n ~/ _DIGIT_BITS]
821 __ add(R7, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 821 __ add(R7, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
822 __ add(R7, R7, Operand(R0, LSL, 2)); 822 __ add(R7, R7, Operand(R0, LSL, 2));
823 // R6 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1] 823 // R6 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
824 __ add(R0, R0, Operand(1)); 824 __ add(R0, R0, Operand(1));
(...skipping 22 matching lines...) Expand all
847 __ Ret(); 847 __ Ret();
848 } 848 }
849 849
850 850
851 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { 851 void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
852 // static void _absAdd(Uint32List digits, int used, 852 // static void _absAdd(Uint32List digits, int used,
853 // Uint32List a_digits, int a_used, 853 // Uint32List a_digits, int a_used,
854 // Uint32List r_digits) 854 // Uint32List r_digits)
855 855
856 // R2 = used, R3 = digits 856 // R2 = used, R3 = digits
857 __ ldrd(R2, SP, 3 * kWordSize); 857 __ ldrd(R2, R3, SP, 3 * kWordSize);
858 // R3 = &digits[0] 858 // R3 = &digits[0]
859 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 859 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
860 860
861 // R4 = a_used, R5 = a_digits 861 // R4 = a_used, R5 = a_digits
862 __ ldrd(R4, SP, 1 * kWordSize); 862 __ ldrd(R4, R5, SP, 1 * kWordSize);
863 // R5 = &a_digits[0] 863 // R5 = &a_digits[0]
864 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); 864 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
865 865
866 // R6 = r_digits 866 // R6 = r_digits
867 __ ldr(R6, Address(SP, 0 * kWordSize)); 867 __ ldr(R6, Address(SP, 0 * kWordSize));
868 // R6 = &r_digits[0] 868 // R6 = &r_digits[0]
869 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); 869 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
870 870
871 // R7 = &digits[a_used >> 1], a_used is Smi. 871 // R7 = &digits[a_used >> 1], a_used is Smi.
872 __ add(R7, R3, Operand(R4, LSL, 1)); 872 __ add(R7, R3, Operand(R4, LSL, 1));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 __ Ret(); 907 __ Ret();
908 } 908 }
909 909
910 910
911 void Intrinsifier::Bigint_absSub(Assembler* assembler) { 911 void Intrinsifier::Bigint_absSub(Assembler* assembler) {
912 // static void _absSub(Uint32List digits, int used, 912 // static void _absSub(Uint32List digits, int used,
913 // Uint32List a_digits, int a_used, 913 // Uint32List a_digits, int a_used,
914 // Uint32List r_digits) 914 // Uint32List r_digits)
915 915
916 // R2 = used, R3 = digits 916 // R2 = used, R3 = digits
917 __ ldrd(R2, SP, 3 * kWordSize); 917 __ ldrd(R2, R3, SP, 3 * kWordSize);
918 // R3 = &digits[0] 918 // R3 = &digits[0]
919 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 919 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
920 920
921 // R4 = a_used, R5 = a_digits 921 // R4 = a_used, R5 = a_digits
922 __ ldrd(R4, SP, 1 * kWordSize); 922 __ ldrd(R4, R5, SP, 1 * kWordSize);
923 // R5 = &a_digits[0] 923 // R5 = &a_digits[0]
924 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); 924 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
925 925
926 // R6 = r_digits 926 // R6 = r_digits
927 __ ldr(R6, Address(SP, 0 * kWordSize)); 927 __ ldr(R6, Address(SP, 0 * kWordSize));
928 // R6 = &r_digits[0] 928 // R6 = &r_digits[0]
929 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); 929 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
930 930
931 // R7 = &digits[a_used >> 1], a_used is Smi. 931 // R7 = &digits[a_used >> 1], a_used is Smi.
932 __ add(R7, R3, Operand(R4, LSL, 1)); 932 __ add(R7, R3, Operand(R4, LSL, 1));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 // while (c != 0) { 987 // while (c != 0) {
988 // uint64_t t = *ajp + c; 988 // uint64_t t = *ajp + c;
989 // *ajp++ = low32(t); 989 // *ajp++ = low32(t);
990 // c = high32(t); // c == 0 or 1. 990 // c = high32(t); // c == 0 or 1.
991 // } 991 // }
992 // return 1; 992 // return 1;
993 // } 993 // }
994 994
995 Label done; 995 Label done;
996 // R3 = x, no_op if x == 0 996 // R3 = x, no_op if x == 0
997 __ ldrd(R0, SP, 5 * kWordSize); // R0 = xi as Smi, R1 = x_digits. 997 __ ldrd(R0, R1, SP, 5 * kWordSize); // R0 = xi as Smi, R1 = x_digits.
998 __ add(R1, R1, Operand(R0, LSL, 1)); 998 __ add(R1, R1, Operand(R0, LSL, 1));
999 __ ldr(R3, FieldAddress(R1, TypedData::data_offset())); 999 __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
1000 __ tst(R3, Operand(R3)); 1000 __ tst(R3, Operand(R3));
1001 __ b(&done, EQ); 1001 __ b(&done, EQ);
1002 1002
1003 // R6 = SmiUntag(n), no_op if n == 0 1003 // R6 = SmiUntag(n), no_op if n == 0
1004 __ ldr(R6, Address(SP, 0 * kWordSize)); 1004 __ ldr(R6, Address(SP, 0 * kWordSize));
1005 __ Asrs(R6, R6, Operand(kSmiTagSize)); 1005 __ Asrs(R6, R6, Operand(kSmiTagSize));
1006 __ b(&done, EQ); 1006 __ b(&done, EQ);
1007 1007
1008 // R4 = mip = &m_digits[i >> 1] 1008 // R4 = mip = &m_digits[i >> 1]
1009 __ ldrd(R0, SP, 3 * kWordSize); // R0 = i as Smi, R1 = m_digits. 1009 __ ldrd(R0, R1, SP, 3 * kWordSize); // R0 = i as Smi, R1 = m_digits.
1010 __ add(R1, R1, Operand(R0, LSL, 1)); 1010 __ add(R1, R1, Operand(R0, LSL, 1));
1011 __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag)); 1011 __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
1012 1012
1013 // R5 = ajp = &a_digits[j >> 1] 1013 // R5 = ajp = &a_digits[j >> 1]
1014 __ ldrd(R0, SP, 1 * kWordSize); // R0 = j as Smi, R1 = a_digits. 1014 __ ldrd(R0, R1, SP, 1 * kWordSize); // R0 = j as Smi, R1 = a_digits.
1015 __ add(R1, R1, Operand(R0, LSL, 1)); 1015 __ add(R1, R1, Operand(R0, LSL, 1));
1016 __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag)); 1016 __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
1017 1017
1018 // R1 = c = 0 1018 // R1 = c = 0
1019 __ mov(R1, Operand(0)); 1019 __ mov(R1, Operand(0));
1020 1020
1021 Label muladd_loop; 1021 Label muladd_loop;
1022 __ Bind(&muladd_loop); 1022 __ Bind(&muladd_loop);
1023 // x: R3 1023 // x: R3
1024 // mip: R4 1024 // mip: R4
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 // c = high64(t); // 33-bit. 1087 // c = high64(t); // 33-bit.
1088 // } 1088 // }
1089 // uint32_t aj = *ajp; 1089 // uint32_t aj = *ajp;
1090 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit. 1090 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit.
1091 // *ajp++ = low32(t); 1091 // *ajp++ = low32(t);
1092 // *ajp = high32(t); 1092 // *ajp = high32(t);
1093 // return 1; 1093 // return 1;
1094 // } 1094 // }
1095 1095
1096 // R4 = xip = &x_digits[i >> 1] 1096 // R4 = xip = &x_digits[i >> 1]
1097 __ ldrd(R2, SP, 2 * kWordSize); // R2 = i as Smi, R3 = x_digits 1097 __ ldrd(R2, R3, SP, 2 * kWordSize); // R2 = i as Smi, R3 = x_digits
1098 __ add(R3, R3, Operand(R2, LSL, 1)); 1098 __ add(R3, R3, Operand(R2, LSL, 1));
1099 __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); 1099 __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
1100 1100
1101 // R3 = x = *xip++, return if x == 0 1101 // R3 = x = *xip++, return if x == 0
1102 Label x_zero; 1102 Label x_zero;
1103 __ ldr(R3, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex)); 1103 __ ldr(R3, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
1104 __ tst(R3, Operand(R3)); 1104 __ tst(R3, Operand(R3));
1105 __ b(&x_zero, EQ); 1105 __ b(&x_zero, EQ);
1106 1106
1107 // R5 = ajp = &a_digits[i] 1107 // R5 = ajp = &a_digits[i]
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 __ Bind(&done); 1165 __ Bind(&done);
1166 // uint32_t aj = *ajp 1166 // uint32_t aj = *ajp
1167 __ ldr(R0, Address(R5, 0)); 1167 __ ldr(R0, Address(R5, 0));
1168 1168
1169 // uint64_t t = aj + c 1169 // uint64_t t = aj + c
1170 __ adds(R6, R6, Operand(R0)); 1170 __ adds(R6, R6, Operand(R0));
1171 __ adc(R7, R7, Operand(0)); 1171 __ adc(R7, R7, Operand(0));
1172 1172
1173 // *ajp = low32(t) = R6 1173 // *ajp = low32(t) = R6
1174 // *(ajp + 1) = high32(t) = R7 1174 // *(ajp + 1) = high32(t) = R7
1175 __ strd(R6, R5, 0); 1175 __ strd(R6, R7, R5, 0);
1176 1176
1177 __ Bind(&x_zero); 1177 __ Bind(&x_zero);
1178 __ mov(R0, Operand(Smi::RawValue(1))); // One digit processed. 1178 __ mov(R0, Operand(Smi::RawValue(1))); // One digit processed.
1179 __ Ret(); 1179 __ Ret();
1180 } 1180 }
1181 1181
1182 1182
1183 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1183 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
1184 // No unsigned 64-bit / 32-bit divide instruction. 1184 // No unsigned 64-bit / 32-bit divide instruction.
1185 } 1185 }
(...skipping 10 matching lines...) Expand all
1196 // } 1196 // }
1197 1197
1198 // R4 = args 1198 // R4 = args
1199 __ ldr(R4, Address(SP, 2 * kWordSize)); // args 1199 __ ldr(R4, Address(SP, 2 * kWordSize)); // args
1200 1200
1201 // R3 = rho = args[2] 1201 // R3 = rho = args[2]
1202 __ ldr(R3, FieldAddress(R4, 1202 __ ldr(R3, FieldAddress(R4,
1203 TypedData::data_offset() + 2*Bigint::kBytesPerDigit)); 1203 TypedData::data_offset() + 2*Bigint::kBytesPerDigit));
1204 1204
1205 // R2 = digits[i >> 1] 1205 // R2 = digits[i >> 1]
1206 __ ldrd(R0, SP, 0 * kWordSize); // R0 = i as Smi, R1 = digits 1206 __ ldrd(R0, R1, SP, 0 * kWordSize); // R0 = i as Smi, R1 = digits
1207 __ add(R1, R1, Operand(R0, LSL, 1)); 1207 __ add(R1, R1, Operand(R0, LSL, 1));
1208 __ ldr(R2, FieldAddress(R1, TypedData::data_offset())); 1208 __ ldr(R2, FieldAddress(R1, TypedData::data_offset()));
1209 1209
1210 // R1:R0 = t = rho*d 1210 // R1:R0 = t = rho*d
1211 __ umull(R0, R1, R2, R3); 1211 __ umull(R0, R1, R2, R3);
1212 1212
1213 // args[4] = t mod DIGIT_BASE = low32(t) 1213 // args[4] = t mod DIGIT_BASE = low32(t)
1214 __ str(R0, 1214 __ str(R0,
1215 FieldAddress(R4, TypedData::data_offset() + 4*Bigint::kBytesPerDigit)); 1215 FieldAddress(R4, TypedData::data_offset() + 4*Bigint::kBytesPerDigit));
1216 1216
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 2004
2005 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { 2005 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
2006 __ LoadIsolate(R0); 2006 __ LoadIsolate(R0);
2007 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); 2007 __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
2008 __ Ret(); 2008 __ Ret();
2009 } 2009 }
2010 2010
2011 } // namespace dart 2011 } // namespace dart
2012 2012
2013 #endif // defined TARGET_ARCH_ARM 2013 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698