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

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

Issue 638983002: Implement bigint mulAdd and sqrAdd intrinsics on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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_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 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 // TODO(regis): Implement. 906 // TODO(regis): Implement.
907 } 907 }
908 908
909 909
910 void Intrinsifier::Bigint_absSub(Assembler* assembler) { 910 void Intrinsifier::Bigint_absSub(Assembler* assembler) {
911 // TODO(regis): Implement. 911 // TODO(regis): Implement.
912 } 912 }
913 913
914 914
915 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { 915 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
916 // TODO(regis): Implement. 916 if (TargetCPUFeatures::arm_version() != ARMv7) return;
Cutch 2014/10/08 15:22:26 if (TargetCPUFeatures::arm_version() != ARMv7) {
regis 2014/10/08 16:58:00 Done.
917 // Pseudo code:
918 // static void _mulAdd(Uint32List x_digits, int xi,
919 // Uint32List m_digits, int i,
920 // Uint32List a_digits, int j, int n) {
921 // uint32_t x = x_digits[xi >> 1]; // xi is Smi.
922 // if (x == 0 || n == 0) {
923 // return;
924 // }
925 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi.
926 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi.
927 // uint32_t c = 0;
928 // SmiUntag(n);
929 // do {
930 // uint32_t mi = *mip++;
931 // uint32_t aj = *ajp;
932 // uint64_t t = x*mi + aj + c; // 32-bit * 32-bit -> 64-bit.
933 // *ajp++ = low32(t);
934 // c = high32(t);
935 // } while (--n > 0);
936 // while (c != 0) {
937 // uint64_t t = *ajp + c;
938 // *ajp++ = low32(t);
939 // c = high32(t); // c == 0 or 1.
940 // }
941 // }
942
943 Label done;
944 // R3 = x, no_op if x == 0
945 __ ldr(R1, Address(SP, 6 * kWordSize)); // x_digits
946 __ ldr(R0, Address(SP, 5 * kWordSize)); // xi is Smi
947 __ add(R1, R1, Operand(R0, LSL, 1));
948 __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
949 __ tst(R3, Operand(R3));
950 __ b(&done, EQ);
951
952 // R6 = SmiUntag(n), no_op if n == 0
953 __ ldr(R6, Address(SP, 0 * kWordSize));
954 __ Asrs(R6, R6, Operand(kSmiTagSize));
955 __ b(&done, EQ);
956
957 // R4 = mip = &m_digits[i >> 1]
958 __ ldr(R1, Address(SP, 4 * kWordSize)); // m_digits
959 __ ldr(R0, Address(SP, 3 * kWordSize)); // i is Smi
960 __ add(R1, R1, Operand(R0, LSL, 1));
961 __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
962
963 // R5 = ajp = &a_digits[j >> 1]
964 __ ldr(R1, Address(SP, 2 * kWordSize)); // a_digits
965 __ ldr(R0, Address(SP, 1 * kWordSize)); // j is Smi
966 __ add(R1, R1, Operand(R0, LSL, 1));
967 __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
968
969 // R1 = c = 0
970 __ mov(R1, Operand(0));
971
972 Label muladd_loop;
973 __ Bind(&muladd_loop);
974 // x: R3
975 // mip: R4
976 // ajp: R5
977 // c: R1
978 // n: R6
979
980 // uint32_t mi = *mip++
981 __ ldr(R2, Address(R4, kWordSize, Address::PostIndex));
982
983 // uint32_t aj = *ajp
984 __ ldr(R0, Address(R5, 0));
985
986 // uint64_t t = x*mi + aj + c
987 __ umaal(R0, R1, R2, R3); // R1:R0 = R2*R3 + R1 + R0.
988
989 // *ajp++ = low32(t) = R0
990 __ str(R0, Address(R5, kWordSize, Address::PostIndex));
991
992 // c = high32(t) = R1
993
994 // while (--n > 0)
995 __ subs(R6, R6, Operand(1)); // --n
996 __ b(&muladd_loop, NE);
997
998 __ tst(R1, Operand(R1));
999 __ b(&done, EQ);
1000
1001 // *ajp++ += c
1002 __ ldr(R0, Address(R5, 0));
1003 __ adds(R0, R0, Operand(R1));
1004 __ str(R0, Address(R5, kWordSize, Address::PostIndex));
1005 __ b(&done, CC);
1006
1007 Label propagate_carry_loop;
1008 __ Bind(&propagate_carry_loop);
1009 __ ldr(R0, Address(R5, 0));
1010 __ adds(R0, R0, Operand(1));
1011 __ str(R0, Address(R5, kWordSize, Address::PostIndex));
1012 __ b(&propagate_carry_loop, CS);
1013
1014 __ Bind(&done);
1015 __ Ret();
917 } 1016 }
918 1017
919 1018
920 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { 1019 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
921 // TODO(regis): Implement. 1020 if (TargetCPUFeatures::arm_version() != ARMv7) return;
1021 // Pseudo code:
1022 // static void _sqrAdd(Uint32List x_digits, int i,
1023 // Uint32List a_digits, int used) {
1024 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi.
1025 // uint32_t x = *xip++;
1026 // if (x == 0) return;
1027 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi.
1028 // uint32_t aj = *ajp;
1029 // uint64_t t = x*x + aj;
1030 // *ajp++ = low32(t);
1031 // uint64_t c = high32(t);
1032 // int n = ((used - i) >> 1) - 1; // used and i are Smi.
1033 // while (--n >= 0) {
1034 // uint32_t xi = *xip++;
1035 // uint32_t aj = *ajp;
1036 // uint96_t t = 2*x*xi + aj + c; // 2-bit * 32-bit * 32-bit -> 65-bit.
1037 // *ajp++ = low32(t);
1038 // c = high64(t); // 33-bit.
1039 // }
1040 // uint32_t aj = *ajp;
1041 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit.
1042 // *ajp++ = low32(t);
1043 // *ajp = high32(t);
1044 // }
1045
1046 // R4 = xip = &x_digits[i >> 1]
1047 __ ldr(R1, Address(SP, 3 * kWordSize)); // x_digits
1048 __ ldr(R6, Address(SP, 2 * kWordSize)); // i is Smi
1049 __ add(R1, R1, Operand(R6, LSL, 1));
1050 __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
1051
1052 // R3 = x = *xip++, return if x == 0
1053 Label x_zero;
1054 __ ldr(R3, Address(R4, kWordSize, Address::PostIndex));
1055 __ tst(R3, Operand(R3));
1056 __ b(&x_zero, EQ);
1057
1058 // R5 = ajp = &a_digits[i]
1059 __ ldr(R1, Address(SP, 1 * kWordSize)); // a_digits
1060 __ add(R1, R1, Operand(R6, LSL, 2)); // j == 2*i, i is Smi.
1061 __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
1062
1063 // R7:R0 = t = x*x + *ajp
1064 __ ldr(R0, Address(R5, 0));
1065 __ mov(R7, Operand(0));
1066 __ umaal(R0, R7, R3, R3); // R7:R0 = R3*R3 + R7 + R0.
1067
1068 // *ajp++ = low32(t) = R0
1069 __ str(R0, Address(R5, kWordSize, Address::PostIndex));
1070
1071 // R7 = low32(c) = high32(t)
1072 // R8 = high32(c) = 0
1073 __ mov(R8, Operand(0));
1074
1075 // int n = used - i - 1
1076 __ ldr(R0, Address(SP, 0 * kWordSize)); // used is Smi
1077 __ sub(R6, R0, Operand(R6));
1078 __ mov(R0, Operand(2)); // while (--n >= 0)
1079 __ rsbs(R6, R0, Operand(R6, ASR, kSmiTagSize));
1080
1081 Label loop, done;
1082 __ b(&done, MI);
1083
1084 __ Bind(&loop);
1085 // x: R3
1086 // xip: R4
1087 // ajp: R5
1088 // c: R8:R7
1089 // t: R2:R1:R0 (not live at loop entry)
1090 // n: R6
1091
1092 // uint32_t xi = *xip++
1093 __ ldr(R2, Address(R4, kWordSize, Address::PostIndex));
1094
1095 // uint32_t aj = *ajp
1096 __ ldr(R1, Address(R5, 0));
1097
1098 // uint96_t t = R2:R1:R0 = 2*x*xi + aj + c
1099 __ mov(R0, Operand(0));
1100 __ umaal(R0, R1, R2, R3); // R1:R0 = R3*R2 + R1 + R0 = x*xi + aj + 0.
1101 __ umlal(R7, R8, R2, R3); // R8:R7 += R3*R2; c += x*xi.
1102 __ adds(R0, R0, Operand(R7));
1103 __ adcs(R7, R1, Operand(R8));
1104 __ mov(R8, Operand(0));
1105 __ adc(R8, R8, Operand(0)); // R8:R7:R0 = R1:R0 + R8:R7 = 2*x*xi + aj + c.
1106
1107 // *ajp++ = low32(t) = R0
1108 __ str(R0, Address(R5, kWordSize, Address::PostIndex));
1109
1110 // while (--n >= 0)
1111 __ subs(R6, R6, Operand(1)); // --n
1112 __ b(&loop, PL);
1113
1114 __ Bind(&done);
1115 // uint32_t aj = *ajp
1116 __ ldr(R0, Address(R5, 0));
1117
1118 // uint64_t t = aj + c
1119 __ adds(R7, R7, Operand(R0));
1120 __ adc(R8, R8, Operand(0));
1121
1122 // *ajp++ = low32(t)
1123 // *ajp = high32(t)
1124 __ str(R7, Address(R5, 0));
1125 __ str(R8, Address(R5, kWordSize));
1126
1127 __ Bind(&x_zero);
1128 __ Ret();
922 } 1129 }
923 1130
924 1131
925 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1132 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
926 // TODO(regis): Implement. 1133 // TODO(regis): Implement.
927 } 1134 }
928 1135
929 1136
930 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1137 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
931 // TODO(regis): Implement. 1138 // TODO(regis): Implement.
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 Isolate* isolate = Isolate::Current(); 1876 Isolate* isolate = Isolate::Current();
1670 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); 1877 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate));
1671 // Set return value to Isolate::current_tag_. 1878 // Set return value to Isolate::current_tag_.
1672 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); 1879 __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
1673 __ Ret(); 1880 __ Ret();
1674 } 1881 }
1675 1882
1676 } // namespace dart 1883 } // namespace dart
1677 1884
1678 #endif // defined TARGET_ARCH_ARM 1885 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698