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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/mint_compares.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 // 4 //
5 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 EAX); // Result register. 1035 EAX); // Result register.
1036 // EBX and EDI are not objects but integer values. 1036 // EBX and EDI are not objects but integer values.
1037 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); 1037 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
1038 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); 1038 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
1039 __ ret(); 1039 __ ret();
1040 __ Bind(&fall_through); 1040 __ Bind(&fall_through);
1041 return false; 1041 return false;
1042 } 1042 }
1043 1043
1044 1044
1045 static void Push64SmiOrMint(Assembler* assembler,
1046 Register reg,
1047 Register tmp,
1048 Label* not_smi_or_mint) {
1049 Label not_smi, done;
1050 __ testl(reg, Immediate(kSmiTagMask));
1051 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1052 __ SmiUntag(reg);
1053 // Sign extend to 64 bit
1054 __ movl(tmp, reg);
1055 __ sarl(tmp, Immediate(31));
1056 __ pushl(tmp);
1057 __ pushl(reg);
1058 __ jmp(&done);
1059 __ Bind(&not_smi);
1060 __ CompareClassId(reg, kMintCid, tmp);
1061 __ j(NOT_EQUAL, not_smi_or_mint);
1062 // Mint.
1063 __ pushl(FieldAddress(reg, Mint::value_offset() + kWordSize));
1064 __ pushl(FieldAddress(reg, Mint::value_offset()));
1065 __ Bind(&done);
1066 }
1067
1068
1045 static bool CompareIntegers(Assembler* assembler, Condition true_condition) { 1069 static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
1046 Label fall_through, true_label; 1070 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
1047 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1071 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1048 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 1072 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1049 TestBothArgumentsSmis(assembler, &fall_through); 1073 TestBothArgumentsSmis(assembler, &try_mint_smi);
1050 // EAX contains the right argument. 1074 // EAX contains the right argument.
1051 __ cmpl(Address(ESP, + 2 * kWordSize), EAX); 1075 __ cmpl(Address(ESP, + 2 * kWordSize), EAX);
1052 __ j(true_condition, &true_label, Assembler::kNearJump); 1076 __ j(true_condition, &is_true, Assembler::kNearJump);
1077 __ Bind(&is_false);
1053 __ LoadObject(EAX, bool_false); 1078 __ LoadObject(EAX, bool_false);
1054 __ ret(); 1079 __ ret();
1055 __ Bind(&true_label); 1080 __ Bind(&is_true);
1056 __ LoadObject(EAX, bool_true); 1081 __ LoadObject(EAX, bool_true);
1057 __ ret(); 1082 __ ret();
1083
1084 // 64-bit comparison
1085 Condition hi_true_cond, hi_false_cond, lo_false_cond;
1086 switch (true_condition) {
1087 case LESS:
1088 case LESS_EQUAL:
1089 hi_true_cond = LESS;
1090 hi_false_cond = GREATER;
1091 lo_false_cond = (true_condition == LESS) ? ABOVE_EQUAL : ABOVE;
1092 break;
1093 case GREATER:
1094 case GREATER_EQUAL:
1095 hi_true_cond = GREATER;
1096 hi_false_cond = LESS;
1097 lo_false_cond = (true_condition == GREATER) ? BELOW_EQUAL : BELOW;
1098 break;
1099 default:
1100 UNREACHABLE();
1101 }
1102 __ Bind(&try_mint_smi);
1103 // Note that EDX and ECX must be preserved in case we fall through to main
1104 // method.
1105 // EAX contains the right argument.
1106 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Left argument.
1107 // Push left as 64 bit integer.
1108 Push64SmiOrMint(assembler, EBX, EDI, &fall_through);
1109 // Push right as 64 bit integer.
1110 Push64SmiOrMint(assembler, EAX, EDI, &drop_two_fall_through);
1111 __ popl(EBX); // Right.LO.
1112 __ popl(ECX); // Right.HI.
1113 __ popl(EAX); // Left.LO.
1114 __ popl(EDX); // Left.HI.
1115 __ cmpl(EDX, ECX); // cmpl left.HI, right.HI.
1116 __ j(hi_false_cond, &is_false, Assembler::kNearJump);
1117 __ j(hi_true_cond, &is_true, Assembler::kNearJump);
1118 __ cmpl(EAX, EBX); // cmpl left.LO, right.LO.
1119 __ j(lo_false_cond, &is_false, Assembler::kNearJump);
1120 // Else is true.
1121 __ jmp(&is_true);
1122
1123 __ Bind(&drop_two_fall_through);
1124 __ Drop(2);
1058 __ Bind(&fall_through); 1125 __ Bind(&fall_through);
1059 return false; 1126 return false;
1060 } 1127 }
1061 1128
1062 1129
1063 bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
1064 return CompareIntegers(assembler, LESS);
1065 }
1066
1067 1130
1068 bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) { 1131 bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
1069 return CompareIntegers(assembler, LESS); 1132 return CompareIntegers(assembler, LESS);
1070 } 1133 }
1071 1134
1072 1135
1136 bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
1137 return Integer_greaterThanFromInt(assembler);
1138 }
1139
1140
1073 bool Intrinsifier::Integer_greaterThan(Assembler* assembler) { 1141 bool Intrinsifier::Integer_greaterThan(Assembler* assembler) {
1074 return CompareIntegers(assembler, GREATER); 1142 return CompareIntegers(assembler, GREATER);
1075 } 1143 }
1076 1144
1077 1145
1078 bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) { 1146 bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
1079 return CompareIntegers(assembler, LESS_EQUAL); 1147 return CompareIntegers(assembler, LESS_EQUAL);
1080 } 1148 }
1081 1149
1082 1150
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 __ Bind(&is_true); 1731 __ Bind(&is_true);
1664 __ LoadObject(EAX, bool_true); 1732 __ LoadObject(EAX, bool_true);
1665 __ ret(); 1733 __ ret();
1666 return true; 1734 return true;
1667 } 1735 }
1668 1736
1669 #undef __ 1737 #undef __
1670 } // namespace dart 1738 } // namespace dart
1671 1739
1672 #endif // defined TARGET_ARCH_IA32 1740 #endif // defined TARGET_ARCH_IA32
OLDNEW
« 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