Index: runtime/vm/intrinsifier_ia32.cc |
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc |
index 7bc8fd6403cdf8646d2b148787d13211d3970276..b8783d014cef35c554bbc0259ffdf563c280d117 100644 |
--- a/runtime/vm/intrinsifier_ia32.cc |
+++ b/runtime/vm/intrinsifier_ia32.cc |
@@ -814,14 +814,18 @@ void Intrinsifier::Bigint_lsh(Assembler* assembler) { |
// static void _lsh(Uint32List x_digits, int x_used, int n, |
// Uint32List r_digits) |
- __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits |
- __ movl(ECX, Address(ESP, 2 * kWordSize)); // n is Smi |
+ // Preserve THR to free ESI. |
+ __ pushl(THR); |
+ ASSERT(THR == ESI); |
+ |
+ __ movl(EDI, Address(ESP, 5 * kWordSize)); // x_digits |
+ __ movl(ECX, Address(ESP, 3 * kWordSize)); // n is Smi |
__ SmiUntag(ECX); |
- __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits |
+ __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
__ movl(ESI, ECX); |
__ sarl(ESI, Immediate(5)); // ESI = n ~/ _DIGIT_BITS. |
__ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset())); |
- __ movl(ESI, Address(ESP, 3 * kWordSize)); // x_used > 0, Smi. |
+ __ movl(ESI, Address(ESP, 4 * kWordSize)); // x_used > 0, Smi. |
__ SmiUntag(ESI); |
__ decl(ESI); |
__ xorl(EAX, EAX); // EAX = 0. |
@@ -844,6 +848,9 @@ void Intrinsifier::Bigint_lsh(Assembler* assembler) { |
__ Bind(&last); |
__ shldl(EDX, ESI, ECX); // ESI == 0. |
__ movl(Address(EBX, 0), EDX); |
+ |
+ // Restore THR and return. |
+ __ popl(THR); |
// Returning Object::null() is not required, since this method is private. |
__ ret(); |
} |
@@ -853,13 +860,17 @@ void Intrinsifier::Bigint_rsh(Assembler* assembler) { |
// static void _rsh(Uint32List x_digits, int x_used, int n, |
// Uint32List r_digits) |
- __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits |
- __ movl(ECX, Address(ESP, 2 * kWordSize)); // n is Smi |
+ // Preserve THR to free ESI. |
+ __ pushl(THR); |
+ ASSERT(THR == ESI); |
+ |
+ __ movl(EDI, Address(ESP, 5 * kWordSize)); // x_digits |
+ __ movl(ECX, Address(ESP, 3 * kWordSize)); // n is Smi |
__ SmiUntag(ECX); |
- __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits |
+ __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
__ movl(EDX, ECX); |
__ sarl(EDX, Immediate(5)); // EDX = n ~/ _DIGIT_BITS. |
- __ movl(ESI, Address(ESP, 3 * kWordSize)); // x_used > 0, Smi. |
+ __ movl(ESI, Address(ESP, 4 * kWordSize)); // x_used > 0, Smi. |
__ SmiUntag(ESI); |
__ decl(ESI); |
// EDI = &x_digits[x_used - 1]. |
@@ -883,6 +894,9 @@ void Intrinsifier::Bigint_rsh(Assembler* assembler) { |
__ Bind(&last); |
__ shrdl(EDX, ESI, ECX); // ESI == 0. |
__ movl(Address(EBX, 0), EDX); |
+ |
+ // Restore THR and return. |
+ __ popl(THR); |
// Returning Object::null() is not required, since this method is private. |
__ ret(); |
} |
@@ -893,13 +907,17 @@ void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
// Uint32List a_digits, int a_used, |
// Uint32List r_digits) |
- __ movl(EDI, Address(ESP, 5 * kWordSize)); // digits |
- __ movl(EAX, Address(ESP, 4 * kWordSize)); // used is Smi |
+ // Preserve THR to free ESI. |
+ __ pushl(THR); |
+ ASSERT(THR == ESI); |
+ |
+ __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits |
+ __ movl(EAX, Address(ESP, 5 * kWordSize)); // used is Smi |
__ SmiUntag(EAX); // used > 0. |
- __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits |
- __ movl(ECX, Address(ESP, 2 * kWordSize)); // a_used is Smi |
+ __ movl(ESI, Address(ESP, 4 * kWordSize)); // a_digits |
+ __ movl(ECX, Address(ESP, 3 * kWordSize)); // a_used is Smi |
__ SmiUntag(ECX); // a_used > 0. |
- __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits |
+ __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
// Precompute 'used - a_used' now so that carry flag is not lost later. |
__ subl(EAX, ECX); |
@@ -937,6 +955,8 @@ void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
__ adcl(EAX, Immediate(0)); |
__ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); |
+ // Restore THR and return. |
+ __ popl(THR); |
// Returning Object::null() is not required, since this method is private. |
__ ret(); |
} |
@@ -947,13 +967,17 @@ void Intrinsifier::Bigint_absSub(Assembler* assembler) { |
// Uint32List a_digits, int a_used, |
// Uint32List r_digits) |
- __ movl(EDI, Address(ESP, 5 * kWordSize)); // digits |
- __ movl(EAX, Address(ESP, 4 * kWordSize)); // used is Smi |
+ // Preserve THR to free ESI. |
+ __ pushl(THR); |
+ ASSERT(THR == ESI); |
+ |
+ __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits |
+ __ movl(EAX, Address(ESP, 5 * kWordSize)); // used is Smi |
__ SmiUntag(EAX); // used > 0. |
- __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits |
- __ movl(ECX, Address(ESP, 2 * kWordSize)); // a_used is Smi |
+ __ movl(ESI, Address(ESP, 4 * kWordSize)); // a_digits |
+ __ movl(ECX, Address(ESP, 3 * kWordSize)); // a_used is Smi |
__ SmiUntag(ECX); // a_used > 0. |
- __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits |
+ __ movl(EBX, Address(ESP, 2 * kWordSize)); // r_digits |
// Precompute 'used - a_used' now so that carry flag is not lost later. |
__ subl(EAX, ECX); |
@@ -987,6 +1011,8 @@ void Intrinsifier::Bigint_absSub(Assembler* assembler) { |
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); |
__ Bind(&done); |
+ // Restore THR and return. |
+ __ popl(THR); |
// Returning Object::null() is not required, since this method is private. |
__ ret(); |
} |
@@ -1033,14 +1059,18 @@ void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { |
__ SmiUntag(EDX); |
__ j(ZERO, &no_op, Assembler::kNearJump); |
+ // Preserve THR to free ESI. |
+ __ pushl(THR); |
+ ASSERT(THR == ESI); |
+ |
// EDI = mip = &m_digits[i >> 1] |
- __ movl(EDI, Address(ESP, 5 * kWordSize)); // m_digits |
- __ movl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi |
+ __ movl(EDI, Address(ESP, 6 * kWordSize)); // m_digits |
+ __ movl(EAX, Address(ESP, 5 * kWordSize)); // i is Smi |
__ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); |
// ESI = ajp = &a_digits[j >> 1] |
- __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits |
- __ movl(EAX, Address(ESP, 2 * kWordSize)); // j is Smi |
+ __ movl(ESI, Address(ESP, 4 * kWordSize)); // a_digits |
+ __ movl(EAX, Address(ESP, 3 * kWordSize)); // j is Smi |
__ leal(ESI, FieldAddress(ESI, EAX, TIMES_2, TypedData::data_offset())); |
// Save n |
@@ -1099,6 +1129,8 @@ void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { |
__ Bind(&done); |
__ Drop(1); // n |
+ // Restore THR and return. |
+ __ popl(THR); |
__ Bind(&no_op); |
__ movl(EAX, Immediate(Smi::RawValue(1))); // One digit processed. |
@@ -1145,8 +1177,12 @@ void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { |
__ j(EQUAL, &x_zero, Assembler::kNearJump); |
__ addl(EDI, Immediate(Bigint::kBytesPerDigit)); |
+ // Preserve THR to free ESI. |
+ __ pushl(THR); |
+ ASSERT(THR == ESI); |
+ |
// ESI = ajp = &a_digits[i] |
- __ movl(ESI, Address(ESP, 2 * kWordSize)); // a_digits |
+ __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits |
__ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset())); |
// EDX:EAX = t = x*x + *ajp |
@@ -1160,8 +1196,8 @@ void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { |
__ addl(ESI, Immediate(Bigint::kBytesPerDigit)); |
// int n = used - i - 1 |
- __ movl(EAX, Address(ESP, 1 * kWordSize)); // used is Smi |
- __ subl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi |
+ __ movl(EAX, Address(ESP, 2 * kWordSize)); // used is Smi |
+ __ subl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi |
__ SmiUntag(EAX); |
__ decl(EAX); |
__ pushl(EAX); // Save n on stack. |
@@ -1226,7 +1262,9 @@ void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { |
__ movl(Address(ESI, 0), EAX); |
__ movl(Address(ESI, Bigint::kBytesPerDigit), EDX); |
+ // Restore THR and return. |
__ Drop(3); |
+ __ popl(THR); |
__ Bind(&x_zero); |
__ movl(EAX, Immediate(Smi::RawValue(1))); // One digit processed. |
__ ret(); |