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

Unified Diff: runtime/vm/intrinsifier_ia32.cc

Issue 1089003002: Implement bigint shift intrinsics on IA32. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/intrinsifier_arm64.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intrinsifier_ia32.cc
===================================================================
--- runtime/vm/intrinsifier_ia32.cc (revision 45179)
+++ runtime/vm/intrinsifier_ia32.cc (working copy)
@@ -26,6 +26,13 @@
DECLARE_FLAG(bool, enable_type_checks);
+// When entering intrinsics code:
+// ECX: IC Data
+// EDX: Arguments descriptor
+// TOS: Return address
+// The ECX, EDX registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The EBP register should not be modified, because it is used by the profiler.
#define __ assembler->
@@ -572,7 +579,7 @@
__ movl(EAX, EBX);
__ shll(EBX, ECX);
__ xorl(EDI, EDI);
- __ shldl(EDI, EAX);
+ __ shldl(EDI, EAX, ECX);
// Result in EDI (high) and EBX (low).
const Class& mint_class = Class::Handle(
Isolate::Current()->object_store()->mint_class());
@@ -806,12 +813,80 @@
void Intrinsifier::Bigint_lsh(Assembler* assembler) {
- // TODO(regis): Implement.
+ // 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
+ __ SmiUntag(ECX);
+ __ movl(EBX, Address(ESP, 1 * 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.
+ __ SmiUntag(ESI);
+ __ decl(ESI);
+ __ xorl(EAX, EAX); // EAX = 0.
+ __ movl(EDX, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset()));
+ __ shldl(EAX, EDX, ECX);
+ __ movl(Address(EBX, ESI, TIMES_4, Bigint::kBytesPerDigit), EAX);
+ Label last;
+ __ cmpl(ESI, Immediate(0));
+ __ j(EQUAL, &last, Assembler::kNearJump);
+ Label loop;
+ __ Bind(&loop);
+ __ movl(EAX, EDX);
+ __ movl(EDX,
+ FieldAddress(EDI, ESI, TIMES_4,
+ TypedData::data_offset() - Bigint::kBytesPerDigit));
+ __ shldl(EAX, EDX, ECX);
+ __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
+ __ decl(ESI);
+ __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+ __ Bind(&last);
+ __ shldl(EDX, ESI, ECX); // ESI == 0.
+ __ movl(Address(EBX, 0), EDX);
+ // Returning Object::null() is not required, since this method is private.
+ __ ret();
}
void Intrinsifier::Bigint_rsh(Assembler* assembler) {
- // TODO(regis): Implement.
+ // 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
+ __ SmiUntag(ECX);
+ __ movl(EBX, Address(ESP, 1 * kWordSize)); // r_digits
+ __ movl(EDX, ECX);
+ __ sarl(EDX, Immediate(5)); // EDX = n ~/ _DIGIT_BITS.
+ __ movl(ESI, Address(ESP, 3 * kWordSize)); // x_used > 0, Smi.
+ __ SmiUntag(ESI);
+ __ decl(ESI);
+ // EDI = &x_digits[x_used - 1].
+ __ leal(EDI, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset()));
+ __ subl(ESI, EDX);
+ // EBX = &r_digits[x_used - 1 - (n ~/ 32)].
+ __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset()));
+ __ negl(ESI);
+ __ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
+ Label last;
+ __ cmpl(ESI, Immediate(0));
+ __ j(EQUAL, &last, Assembler::kNearJump);
+ Label loop;
+ __ Bind(&loop);
+ __ movl(EAX, EDX);
+ __ movl(EDX, Address(EDI, ESI, TIMES_4, Bigint::kBytesPerDigit));
+ __ shrdl(EAX, EDX, ECX);
+ __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
+ __ incl(ESI);
+ __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+ __ Bind(&last);
+ __ shrdl(EDX, ESI, ECX); // ESI == 0.
+ __ movl(Address(EBX, 0), EDX);
+ // Returning Object::null() is not required, since this method is private.
+ __ ret();
}
« no previous file with comments | « runtime/vm/intrinsifier_arm64.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698