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

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

Issue 811763004: Modify Bigint _mulAdd, _sqrAdd, _estQuotientDigit, and Montgomery _mulMod (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 12 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"
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 __ delay_slot()->addiu(T6, T6, Immediate(Bigint::kBytesPerDigit)); 1030 __ delay_slot()->addiu(T6, T6, Immediate(Bigint::kBytesPerDigit));
1031 1031
1032 __ Bind(&done); 1032 __ Bind(&done);
1033 // Returning Object::null() is not required, since this method is private. 1033 // Returning Object::null() is not required, since this method is private.
1034 __ Ret(); 1034 __ Ret();
1035 } 1035 }
1036 1036
1037 1037
1038 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { 1038 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
1039 // Pseudo code: 1039 // Pseudo code:
1040 // static void _mulAdd(Uint32List x_digits, int xi, 1040 // static int _mulAdd(Uint32List x_digits, int xi,
1041 // Uint32List m_digits, int i, 1041 // Uint32List m_digits, int i,
1042 // Uint32List a_digits, int j, int n) { 1042 // Uint32List a_digits, int j, int n) {
1043 // uint32_t x = x_digits[xi >> 1]; // xi is Smi. 1043 // uint32_t x = x_digits[xi >> 1]; // xi is Smi.
1044 // if (x == 0 || n == 0) { 1044 // if (x == 0 || n == 0) {
1045 // return; 1045 // return 1;
1046 // } 1046 // }
1047 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi. 1047 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi.
1048 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi. 1048 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi.
1049 // uint32_t c = 0; 1049 // uint32_t c = 0;
1050 // SmiUntag(n); 1050 // SmiUntag(n);
1051 // do { 1051 // do {
1052 // uint32_t mi = *mip++; 1052 // uint32_t mi = *mip++;
1053 // uint32_t aj = *ajp; 1053 // uint32_t aj = *ajp;
1054 // uint64_t t = x*mi + aj + c; // 32-bit * 32-bit -> 64-bit. 1054 // uint64_t t = x*mi + aj + c; // 32-bit * 32-bit -> 64-bit.
1055 // *ajp++ = low32(t); 1055 // *ajp++ = low32(t);
1056 // c = high32(t); 1056 // c = high32(t);
1057 // } while (--n > 0); 1057 // } while (--n > 0);
1058 // while (c != 0) { 1058 // while (c != 0) {
1059 // uint64_t t = *ajp + c; 1059 // uint64_t t = *ajp + c;
1060 // *ajp++ = low32(t); 1060 // *ajp++ = low32(t);
1061 // c = high32(t); // c == 0 or 1. 1061 // c = high32(t); // c == 0 or 1.
1062 // } 1062 // }
1063 // return 1;
1063 // } 1064 // }
1064 1065
1065 Label done; 1066 Label done;
1066 // T3 = x, no_op if x == 0 1067 // T3 = x, no_op if x == 0
1067 __ lw(T0, Address(SP, 5 * kWordSize)); // T0 = xi as Smi. 1068 __ lw(T0, Address(SP, 5 * kWordSize)); // T0 = xi as Smi.
1068 __ lw(T1, Address(SP, 6 * kWordSize)); // T1 = x_digits. 1069 __ lw(T1, Address(SP, 6 * kWordSize)); // T1 = x_digits.
1069 __ sll(T0, T0, 1); 1070 __ sll(T0, T0, 1);
1070 __ addu(T1, T0, T1); 1071 __ addu(T1, T0, T1);
1071 __ lw(T3, FieldAddress(T1, TypedData::data_offset())); 1072 __ lw(T3, FieldAddress(T1, TypedData::data_offset()));
1072 __ beq(T3, ZR, &done); 1073 __ beq(T3, ZR, &done);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 1141
1141 Label propagate_carry_loop; 1142 Label propagate_carry_loop;
1142 __ Bind(&propagate_carry_loop); 1143 __ Bind(&propagate_carry_loop);
1143 __ lw(T0, Address(T5, 0)); 1144 __ lw(T0, Address(T5, 0));
1144 __ addiu(T0, T0, Immediate(1)); 1145 __ addiu(T0, T0, Immediate(1));
1145 __ sw(T0, Address(T5, 0)); 1146 __ sw(T0, Address(T5, 0));
1146 __ beq(T0, ZR, &propagate_carry_loop); 1147 __ beq(T0, ZR, &propagate_carry_loop);
1147 __ delay_slot()->addiu(T5, T5, Immediate(Bigint::kBytesPerDigit)); 1148 __ delay_slot()->addiu(T5, T5, Immediate(Bigint::kBytesPerDigit));
1148 1149
1149 __ Bind(&done); 1150 __ Bind(&done);
1150 // Returning Object::null() is not required, since this method is private. 1151 __ addiu(V0, ZR, Immediate(Smi::RawValue(1))); // One digit processed.
1151 __ Ret(); 1152 __ Ret();
1152 } 1153 }
1153 1154
1154 1155
1155 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { 1156 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
1156 // Pseudo code: 1157 // Pseudo code:
1157 // static void _sqrAdd(Uint32List x_digits, int i, 1158 // static int _sqrAdd(Uint32List x_digits, int i,
1158 // Uint32List a_digits, int used) { 1159 // Uint32List a_digits, int used) {
1159 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi. 1160 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi.
1160 // uint32_t x = *xip++; 1161 // uint32_t x = *xip++;
1161 // if (x == 0) return; 1162 // if (x == 0) return 1;
1162 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi. 1163 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi.
1163 // uint32_t aj = *ajp; 1164 // uint32_t aj = *ajp;
1164 // uint64_t t = x*x + aj; 1165 // uint64_t t = x*x + aj;
1165 // *ajp++ = low32(t); 1166 // *ajp++ = low32(t);
1166 // uint64_t c = high32(t); 1167 // uint64_t c = high32(t);
1167 // int n = ((used - i) >> 1) - 1; // used and i are Smi. 1168 // int n = ((used - i) >> 1) - 1; // used and i are Smi.
1168 // while (--n >= 0) { 1169 // while (--n >= 0) {
1169 // uint32_t xi = *xip++; 1170 // uint32_t xi = *xip++;
1170 // uint32_t aj = *ajp; 1171 // uint32_t aj = *ajp;
1171 // uint96_t t = 2*x*xi + aj + c; // 2-bit * 32-bit * 32-bit -> 65-bit. 1172 // uint96_t t = 2*x*xi + aj + c; // 2-bit * 32-bit * 32-bit -> 65-bit.
1172 // *ajp++ = low32(t); 1173 // *ajp++ = low32(t);
1173 // c = high64(t); // 33-bit. 1174 // c = high64(t); // 33-bit.
1174 // } 1175 // }
1175 // uint32_t aj = *ajp; 1176 // uint32_t aj = *ajp;
1176 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit. 1177 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit.
1177 // *ajp++ = low32(t); 1178 // *ajp++ = low32(t);
1178 // *ajp = high32(t); 1179 // *ajp = high32(t);
1180 // return 1;
1179 // } 1181 // }
1180 1182
1181 // T4 = xip = &x_digits[i >> 1] 1183 // T4 = xip = &x_digits[i >> 1]
1182 __ lw(T2, Address(SP, 2 * kWordSize)); // T2 = i as Smi. 1184 __ lw(T2, Address(SP, 2 * kWordSize)); // T2 = i as Smi.
1183 __ lw(T3, Address(SP, 3 * kWordSize)); // T3 = x_digits. 1185 __ lw(T3, Address(SP, 3 * kWordSize)); // T3 = x_digits.
1184 __ sll(T0, T2, 1); 1186 __ sll(T0, T2, 1);
1185 __ addu(T3, T0, T3); 1187 __ addu(T3, T0, T3);
1186 __ addiu(T4, T3, Immediate(TypedData::data_offset() - kHeapObjectTag)); 1188 __ addiu(T4, T3, Immediate(TypedData::data_offset() - kHeapObjectTag));
1187 1189
1188 // T3 = x = *xip++, return if x == 0 1190 // T3 = x = *xip++, return if x == 0
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 __ addu(T6, T6, T0); 1274 __ addu(T6, T6, T0);
1273 __ sltu(T1, T6, T0); 1275 __ sltu(T1, T6, T0);
1274 __ addu(T7, T7, T1); 1276 __ addu(T7, T7, T1);
1275 1277
1276 // *ajp = low32(t) = T6 1278 // *ajp = low32(t) = T6
1277 // *(ajp + 1) = high32(t) = T7 1279 // *(ajp + 1) = high32(t) = T7
1278 __ sw(T6, Address(T5, 0)); 1280 __ sw(T6, Address(T5, 0));
1279 __ sw(T7, Address(T5, Bigint::kBytesPerDigit)); 1281 __ sw(T7, Address(T5, Bigint::kBytesPerDigit));
1280 1282
1281 __ Bind(&x_zero); 1283 __ Bind(&x_zero);
1282 // Returning Object::null() is not required, since this method is private. 1284 __ addiu(V0, ZR, Immediate(Smi::RawValue(1))); // One digit processed.
1283 __ Ret(); 1285 __ Ret();
1284 } 1286 }
1285 1287
1286 1288
1287 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1289 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
1288 // No unsigned 64-bit / 32-bit divide instruction. 1290 // No unsigned 64-bit / 32-bit divide instruction.
1289 } 1291 }
1290 1292
1291 1293
1292 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1294 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
1293 // Pseudo code: 1295 // Pseudo code:
1294 // static void _mulMod(Uint32List args, Uint32List digits, int i) { 1296 // static int _mulMod(Uint32List args, Uint32List digits, int i) {
1295 // uint32_t rho = args[_RHO]; // _RHO == 0. 1297 // uint32_t rho = args[_RHO]; // _RHO == 2.
1296 // uint32_t d = digits[i >> 1]; // i is Smi. 1298 // uint32_t d = digits[i >> 1]; // i is Smi.
1297 // uint64_t t = rho*d; 1299 // uint64_t t = rho*d;
1298 // args[_MU] = t mod DIGIT_BASE; // _MU == 1. 1300 // args[_MU] = t mod DIGIT_BASE; // _MU == 4.
1301 // return 1;
1299 // } 1302 // }
1300 1303
1301 // T4 = args 1304 // T4 = args
1302 __ lw(T4, Address(SP, 2 * kWordSize)); // args 1305 __ lw(T4, Address(SP, 2 * kWordSize)); // args
1303 1306
1304 // T3 = rho = args[0] 1307 // T3 = rho = args[2]
1305 __ lw(T3, FieldAddress(T4, TypedData::data_offset())); 1308 __ lw(T3,
1309 FieldAddress(T4, TypedData::data_offset() + 2*Bigint::kBytesPerDigit));
1306 1310
1307 // T2 = d = digits[i >> 1] 1311 // T2 = d = digits[i >> 1]
1308 __ lw(T0, Address(SP, 0 * kWordSize)); // T0 = i as Smi. 1312 __ lw(T0, Address(SP, 0 * kWordSize)); // T0 = i as Smi.
1309 __ lw(T1, Address(SP, 1 * kWordSize)); // T1 = digits. 1313 __ lw(T1, Address(SP, 1 * kWordSize)); // T1 = digits.
1310 __ sll(T0, T0, 1); 1314 __ sll(T0, T0, 1);
1311 __ addu(T1, T0, T1); 1315 __ addu(T1, T0, T1);
1312 __ lw(T2, FieldAddress(T1, TypedData::data_offset())); 1316 __ lw(T2, FieldAddress(T1, TypedData::data_offset()));
1313 1317
1314 // HI:LO = t = rho*d 1318 // HI:LO = t = rho*d
1315 __ multu(T2, T3); 1319 __ multu(T2, T3);
1316 1320
1317 // args[1] = t mod DIGIT_BASE = low32(t) 1321 // args[4] = t mod DIGIT_BASE = low32(t)
1318 __ mflo(T0); 1322 __ mflo(T0);
1319 __ sw(T0, 1323 __ sw(T0,
1320 FieldAddress(T4, TypedData::data_offset() + Bigint::kBytesPerDigit)); 1324 FieldAddress(T4, TypedData::data_offset() + 4*Bigint::kBytesPerDigit));
1321 1325
1322 // Returning Object::null() is not required, since this method is private. 1326 __ addiu(V0, ZR, Immediate(Smi::RawValue(1))); // One digit processed.
1323 __ Ret(); 1327 __ Ret();
1324 } 1328 }
1325 1329
1326 1330
1327 // Check if the last argument is a double, jump to label 'is_smi' if smi 1331 // Check if the last argument is a double, jump to label 'is_smi' if smi
1328 // (easy to convert to double), otherwise jump to label 'not_double_smi', 1332 // (easy to convert to double), otherwise jump to label 'not_double_smi',
1329 // Returns the last argument in T0. 1333 // Returns the last argument in T0.
1330 static void TestLastArgumentIsDouble(Assembler* assembler, 1334 static void TestLastArgumentIsDouble(Assembler* assembler,
1331 Label* is_smi, 1335 Label* is_smi,
1332 Label* not_double_smi) { 1336 Label* not_double_smi) {
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after
2139 Isolate* isolate = Isolate::Current(); 2143 Isolate* isolate = Isolate::Current();
2140 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate)); 2144 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate));
2141 // Set return value. 2145 // Set return value.
2142 __ Ret(); 2146 __ Ret();
2143 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); 2147 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset()));
2144 } 2148 }
2145 2149
2146 } // namespace dart 2150 } // namespace dart
2147 2151
2148 #endif // defined TARGET_ARCH_MIPS 2152 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698