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

Unified Diff: runtime/vm/intrinsifier_ia32.cc

Issue 11262019: Intrinsify Mint/Smi combined comparisons by extending a Smi to a 64 bit integer and doing a 64-bit … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | « no previous file | tests/language/mint_compares.dart » ('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 14048)
+++ runtime/vm/intrinsifier_ia32.cc (working copy)
@@ -1042,31 +1042,99 @@
}
+static void Push64SmiOrMint(Assembler* assembler,
+ Register reg,
+ Register tmp,
+ Label* not_smi_or_mint) {
+ Label not_smi, done;
+ __ testl(reg, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
+ __ SmiUntag(reg);
+ // Sign extend to 64 bit
+ __ movl(tmp, reg);
+ __ sarl(tmp, Immediate(31));
+ __ pushl(tmp);
+ __ pushl(reg);
+ __ jmp(&done);
+ __ Bind(&not_smi);
+ __ CompareClassId(reg, kMintCid, tmp);
+ __ j(NOT_EQUAL, not_smi_or_mint);
+ // Mint.
+ __ pushl(FieldAddress(reg, Mint::value_offset() + kWordSize));
+ __ pushl(FieldAddress(reg, Mint::value_offset()));
+ __ Bind(&done);
+}
+
+
static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
- Label fall_through, true_label;
+ Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
const Bool& bool_true = Bool::ZoneHandle(Bool::True());
const Bool& bool_false = Bool::ZoneHandle(Bool::False());
- TestBothArgumentsSmis(assembler, &fall_through);
+ TestBothArgumentsSmis(assembler, &try_mint_smi);
// EAX contains the right argument.
__ cmpl(Address(ESP, + 2 * kWordSize), EAX);
- __ j(true_condition, &true_label, Assembler::kNearJump);
+ __ j(true_condition, &is_true, Assembler::kNearJump);
+ __ Bind(&is_false);
__ LoadObject(EAX, bool_false);
__ ret();
- __ Bind(&true_label);
+ __ Bind(&is_true);
__ LoadObject(EAX, bool_true);
__ ret();
+
+ // 64-bit comparison
+ Condition hi_true_cond, hi_false_cond, lo_false_cond;
+ switch (true_condition) {
+ case LESS:
+ case LESS_EQUAL:
+ hi_true_cond = LESS;
+ hi_false_cond = GREATER;
+ lo_false_cond = (true_condition == LESS) ? ABOVE_EQUAL : ABOVE;
+ break;
+ case GREATER:
+ case GREATER_EQUAL:
+ hi_true_cond = GREATER;
+ hi_false_cond = LESS;
+ lo_false_cond = (true_condition == GREATER) ? BELOW_EQUAL : BELOW;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ __ Bind(&try_mint_smi);
+ // Note that EDX and ECX must be preserved in case we fall through to main
+ // method.
+ // EAX contains the right argument.
+ __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Left argument.
+ // Push left as 64 bit integer.
+ Push64SmiOrMint(assembler, EBX, EDI, &fall_through);
+ // Push right as 64 bit integer.
+ Push64SmiOrMint(assembler, EAX, EDI, &drop_two_fall_through);
+ __ popl(EBX); // Right.LO.
+ __ popl(ECX); // Right.HI.
+ __ popl(EAX); // Left.LO.
+ __ popl(EDX); // Left.HI.
+ __ cmpl(EDX, ECX); // cmpl left.HI, right.HI.
+ __ j(hi_false_cond, &is_false, Assembler::kNearJump);
+ __ j(hi_true_cond, &is_true, Assembler::kNearJump);
+ __ cmpl(EAX, EBX); // cmpl left.LO, right.LO.
+ __ j(lo_false_cond, &is_false, Assembler::kNearJump);
+ // Else is true.
+ __ jmp(&is_true);
+
+ __ Bind(&drop_two_fall_through);
+ __ Drop(2);
__ Bind(&fall_through);
return false;
}
-bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
+
+bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
return CompareIntegers(assembler, LESS);
}
-bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
- return CompareIntegers(assembler, LESS);
+bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
+ return Integer_greaterThanFromInt(assembler);
}
« no previous file with comments | « no previous file | tests/language/mint_compares.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698