| 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();
|
|
|