Chromium Code Reviews| Index: runtime/vm/intrinsifier_x64.cc |
| =================================================================== |
| --- runtime/vm/intrinsifier_x64.cc (revision 41744) |
| +++ runtime/vm/intrinsifier_x64.cc (working copy) |
| @@ -837,32 +837,74 @@ |
| // Precompute 'used - a_used' now so that carry flag is not lost later. |
| __ subq(R8, RCX); |
| - __ incq(R8); // To account for the extra test between loops. |
| + // Process two 32-bit digits at a time as a 64-bit value. |
| + __ movq(R9, RCX); |
| + __ shrq(R9, Immediate(1)); // R9 = a_used / 2. |
| + __ shlq(RCX, Immediate(63)); |
| + __ shrq(RCX, Immediate(63)); // RCX = a_used % 2. |
| + __ movq(R10, R8); |
| + __ shrq(R10, Immediate(1)); // R10 = (used - a_used) / 2. |
| + __ shlq(R8, Immediate(63)); |
| + __ shrq(R8, Immediate(63)); // R8 = (used - a_used) % 2. |
| + |
| + // Account for the extra guard tests. |
| + __ incq(RCX); |
| + __ incq(R8); |
| + __ incq(R9); |
| + __ incq(R10); |
| + |
| __ xorq(RDX, RDX); // RDX = 0, carry flag = 0. |
| - Label add_loop; |
| - __ Bind(&add_loop); |
| - // Loop a_used times, RCX = a_used, RCX > 0. |
| + Label add32; |
| + __ decq(R9); // Does not affect carry flag. |
| + __ j(ZERO, &add32, Assembler::kNearJump); // a_used == 1. |
| + |
| + Label add64_loop; |
| + __ Bind(&add64_loop); |
| + // Loop a_used/2 times, R9 = a_used/2, a_used > 0. |
| + __ movq(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset())); |
| + __ adcq(RAX, FieldAddress(RSI, RDX, TIMES_4, TypedData::data_offset())); |
| + __ movq(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX); |
| + __ incq(RDX); // Does not affect carry flag. |
|
zra
2014/11/14 22:11:54
Is it possible to put these incq's and decq's in b
|
| + __ incq(RDX); // Does not affect carry flag. |
| + __ decq(R9); // Does not affect carry flag. |
| + __ j(NOT_ZERO, &add64_loop, Assembler::kNearJump); |
| + |
| + Label carry64_guard; |
| + __ decq(RCX); // Does not affect carry flag. |
| + __ j(ZERO, &carry64_guard, Assembler::kNearJump); |
| + |
| + __ Bind(&add32); |
| __ movl(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset())); |
| __ adcl(RAX, FieldAddress(RSI, RDX, TIMES_4, TypedData::data_offset())); |
| __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX); |
| __ incq(RDX); // Does not affect carry flag. |
| - __ decq(RCX); // Does not affect carry flag. |
| - __ j(NOT_ZERO, &add_loop, Assembler::kNearJump); |
| + Label carry32_guard; |
| + __ Bind(&carry64_guard); |
| + __ decq(R10); // Does not affect carry flag. |
| + __ j(ZERO, &carry32_guard, Assembler::kNearJump); |
| + |
| + Label carry64_loop; |
| + __ Bind(&carry64_loop); |
| + // Loop (used - a_used)/2 times, R10 = (used - a_used)/2. |
| + __ movq(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset())); |
| + __ adcq(RAX, Immediate(0)); |
| + __ movq(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX); |
| + __ incq(RDX); // Does not affect carry flag. |
|
zra
2014/11/14 22:11:54
Same comment.
|
| + __ incq(RDX); // Does not affect carry flag. |
| + __ decq(R10); // Does not affect carry flag. |
| + __ j(NOT_ZERO, &carry64_loop, Assembler::kNearJump); |
| + |
| Label last_carry; |
| + __ Bind(&carry32_guard); |
| __ decq(R8); // Does not affect carry flag. |
| - __ j(ZERO, &last_carry, Assembler::kNearJump); // If used - a_used == 0. |
| + __ j(ZERO, &last_carry, Assembler::kNearJump); |
| - Label carry_loop; |
| - __ Bind(&carry_loop); |
| - // Loop used - a_used times, R8 = used - a_used, R8 > 0. |
| __ movl(RAX, FieldAddress(RDI, RDX, TIMES_4, TypedData::data_offset())); |
| __ adcl(RAX, Immediate(0)); |
| __ movl(FieldAddress(RBX, RDX, TIMES_4, TypedData::data_offset()), RAX); |
| __ incq(RDX); // Does not affect carry flag. |
| - __ decq(R8); // Does not affect carry flag. |
| - __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); |
| __ Bind(&last_carry); |
| __ movl(RAX, Immediate(0)); |