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

Side by Side Diff: src/codegen-ia32.cc

Issue 16481: Copy of changelist from issue 16450. Converts compare operation... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 12 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 | « src/assembler-ia32.cc ('k') | src/disasm-ia32.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 strict_ ? "true" : "false"); 1178 strict_ ? "true" : "false");
1179 } 1179 }
1180 #endif 1180 #endif
1181 }; 1181 };
1182 1182
1183 1183
1184 void CodeGenerator::Comparison(Condition cc, bool strict) { 1184 void CodeGenerator::Comparison(Condition cc, bool strict) {
1185 // Strict only makes sense for equality comparisons. 1185 // Strict only makes sense for equality comparisons.
1186 ASSERT(!strict || cc == equal); 1186 ASSERT(!strict || cc == equal);
1187 1187
1188 Result left_side(this);
1189 Result right_side(this);
1188 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. 1190 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
1189 if (cc == greater || cc == less_equal) { 1191 if (cc == greater || cc == less_equal) {
1190 cc = ReverseCondition(cc); 1192 cc = ReverseCondition(cc);
1191 frame_->EmitPop(edx); 1193 left_side = frame_->Pop();
1192 frame_->EmitPop(eax); 1194 right_side = frame_->Pop();
1193 } else { 1195 } else {
1194 frame_->EmitPop(eax); 1196 right_side = frame_->Pop();
1195 frame_->EmitPop(edx); 1197 left_side = frame_->Pop();
1196 } 1198 }
1197 1199 left_side.ToRegister();
1200 right_side.ToRegister();
1201 ASSERT(left_side.is_valid());
1202 ASSERT(right_side.is_valid());
1198 // Check for the smi case. 1203 // Check for the smi case.
1199 JumpTarget is_smi(this); 1204 JumpTarget is_smi(this);
1200 JumpTarget done(this); 1205 JumpTarget done(this);
1201 __ mov(ecx, Operand(eax)); 1206 Result temp = allocator_->Allocate();
1202 __ or_(ecx, Operand(edx)); 1207 ASSERT(temp.is_valid());
1203 __ test(ecx, Immediate(kSmiTagMask)); 1208 __ mov(temp.reg(), left_side.reg());
1204 is_smi.Branch(zero, taken); 1209 __ or_(temp.reg(), Operand(right_side.reg()));
1210 __ test(temp.reg(), Immediate(kSmiTagMask));
1211 temp.Unuse();
1212 is_smi.Branch(zero, &left_side, &right_side, taken);
1205 1213
1206 // When non-smi, call out to the compare stub. "parameters" setup by 1214 // When non-smi, call out to the compare stub. "parameters" setup by
1207 // calling code in edx and eax and "result" is returned in the flags. 1215 // calling code in edx and eax and "result" is returned in the flags.
1216 if (!left_side.reg().is(eax)) {
1217 right_side.ToRegister(eax);
1218 left_side.ToRegister(edx);
1219 } else if (!right_side.reg().is(edx)) {
1220 left_side.ToRegister(edx);
1221 right_side.ToRegister(eax);
1222 } else {
1223 frame_->Spill(eax); // Can be multiply referenced, even now.
1224 frame_->Spill(edx);
1225 __ xchg(eax, edx);
1226 // If left_side and right_side become real (non-dummy) arguments
1227 // to CallStub, they need to be swapped in this case.
1228 }
1208 CompareStub stub(cc, strict); 1229 CompareStub stub(cc, strict);
1209 frame_->CallStub(&stub, 0); 1230 Result answer = frame_->CallStub(&stub, &right_side, &left_side, 0);
1210 if (cc == equal) { 1231 if (cc == equal) {
1211 __ test(eax, Operand(eax)); 1232 __ test(answer.reg(), Operand(answer.reg()));
1212 } else { 1233 } else {
1213 __ cmp(eax, 0); 1234 __ cmp(answer.reg(), 0);
1214 } 1235 }
1236 answer.Unuse();
1237 // The expected frame at JumpTarget "done" is bound to the current frame.
1238 // This current frame is spilled, due to the call to CallStub.
1239 // It would be better if the fast SMI case controlled the expected frame.
1215 done.Jump(); 1240 done.Jump();
1216 1241
1217 // Test smi equality by pointer comparison. 1242 is_smi.Bind(&left_side, &right_side);
1218 is_smi.Bind(); 1243 __ cmp(left_side.reg(), Operand(right_side.reg()));
1219 __ cmp(edx, Operand(eax)); 1244 right_side.Unuse();
1245 left_side.Unuse();
1220 // Fall through to |done|. 1246 // Fall through to |done|.
1221 1247
1222 done.Bind(); 1248 done.Bind();
1223 cc_reg_ = cc; 1249 cc_reg_ = cc;
1224 } 1250 }
1225 1251
1226 1252
1227 class DeferredSmiComparison: public DeferredCode { 1253 class DeferredSmiComparison: public DeferredCode {
1228 public: 1254 public:
1229 DeferredSmiComparison(CodeGenerator* generator, 1255 DeferredSmiComparison(CodeGenerator* generator,
(...skipping 2935 matching lines...) Expand 10 before | Expand all | Expand 10 after
4165 case Token::GT: 4191 case Token::GT:
4166 cc = greater; 4192 cc = greater;
4167 break; 4193 break;
4168 case Token::LTE: 4194 case Token::LTE:
4169 cc = less_equal; 4195 cc = less_equal;
4170 break; 4196 break;
4171 case Token::GTE: 4197 case Token::GTE:
4172 cc = greater_equal; 4198 cc = greater_equal;
4173 break; 4199 break;
4174 case Token::IN: { 4200 case Token::IN: {
4175 VirtualFrame::SpilledScope spilled_scope(this); 4201 Load(left);
4176 LoadAndSpill(left); 4202 Load(right);
4177 LoadAndSpill(right);
4178 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); 4203 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
4179 frame_->EmitPush(eax); // push the result 4204 frame_->Push(eax); // push the result
4180 return; 4205 return;
4181 } 4206 }
4182 case Token::INSTANCEOF: { 4207 case Token::INSTANCEOF: {
4183 VirtualFrame::SpilledScope spilled_scope(this); 4208 Load(left);
4184 LoadAndSpill(left); 4209 Load(right);
4185 LoadAndSpill(right);
4186 InstanceofStub stub; 4210 InstanceofStub stub;
4187 frame_->CallStub(&stub, 2); 4211 frame_->CallStub(&stub, 2);
4188 __ test(eax, Operand(eax)); 4212 __ test(eax, Operand(eax));
4189 cc_reg_ = zero; 4213 cc_reg_ = zero;
4190 return; 4214 return;
4191 } 4215 }
4192 default: 4216 default:
4193 UNREACHABLE(); 4217 UNREACHABLE();
4194 } 4218 }
4195 4219
4196 // Optimize for the case where (at least) one of the expressions 4220 // Optimize for the case where (at least) one of the expressions
4197 // is a literal small integer. 4221 // is a literal small integer.
4198 if (IsInlineSmi(left->AsLiteral())) { 4222 if (IsInlineSmi(left->AsLiteral())) {
4199 Load(right); 4223 Load(right);
4200 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict); 4224 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict);
4201 return; 4225 return;
4202 } 4226 }
4203 if (IsInlineSmi(right->AsLiteral())) { 4227 if (IsInlineSmi(right->AsLiteral())) {
4204 Load(left); 4228 Load(left);
4205 SmiComparison(cc, right->AsLiteral()->handle(), strict); 4229 SmiComparison(cc, right->AsLiteral()->handle(), strict);
4206 return; 4230 return;
4207 } 4231 }
4208 4232
4209 VirtualFrame::SpilledScope spilled_scope(this); 4233 Load(left);
4210 LoadAndSpill(left); 4234 Load(right);
4211 LoadAndSpill(right);
4212 Comparison(cc, strict); 4235 Comparison(cc, strict);
4213 } 4236 }
4214 4237
4215 4238
4216 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { 4239 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) {
4217 return (target == &function_return_ && !function_return_is_shadowed_); 4240 return (target == &function_return_ && !function_return_is_shadowed_);
4218 } 4241 }
4219 4242
4220 4243
4221 #ifdef DEBUG 4244 #ifdef DEBUG
(...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after
5764 5787
5765 // Slow-case: Go through the JavaScript implementation. 5788 // Slow-case: Go through the JavaScript implementation.
5766 __ bind(&slow); 5789 __ bind(&slow);
5767 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5790 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5768 } 5791 }
5769 5792
5770 5793
5771 #undef __ 5794 #undef __
5772 5795
5773 } } // namespace v8::internal 5796 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/assembler-ia32.cc ('k') | src/disasm-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698