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

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

Issue 1207006: Rename NumberInfo to TypeInfo.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: changed project files Created 10 years, 9 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/ia32/codegen-ia32.h ('k') | src/ia32/full-codegen-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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 832 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 __ bind(&ok); 843 __ bind(&ok);
844 } 844 }
845 // In the integer32 case there are no Smis hidden in heap numbers, so we 845 // In the integer32 case there are no Smis hidden in heap numbers, so we
846 // need only test for Smi zero. 846 // need only test for Smi zero.
847 __ test(value.reg(), Operand(value.reg())); 847 __ test(value.reg(), Operand(value.reg()));
848 dest->false_target()->Branch(zero); 848 dest->false_target()->Branch(zero);
849 value.Unuse(); 849 value.Unuse();
850 dest->Split(not_zero); 850 dest->Split(not_zero);
851 } else if (value.is_number()) { 851 } else if (value.is_number()) {
852 Comment cmnt(masm_, "ONLY_NUMBER"); 852 Comment cmnt(masm_, "ONLY_NUMBER");
853 // Fast case if NumberInfo indicates only numbers. 853 // Fast case if TypeInfo indicates only numbers.
854 if (FLAG_debug_code) { 854 if (FLAG_debug_code) {
855 __ AbortIfNotNumber(value.reg()); 855 __ AbortIfNotNumber(value.reg());
856 } 856 }
857 // Smi => false iff zero. 857 // Smi => false iff zero.
858 ASSERT(kSmiTag == 0); 858 ASSERT(kSmiTag == 0);
859 __ test(value.reg(), Operand(value.reg())); 859 __ test(value.reg(), Operand(value.reg()));
860 dest->false_target()->Branch(zero); 860 dest->false_target()->Branch(zero);
861 __ test(value.reg(), Immediate(kSmiTagMask)); 861 __ test(value.reg(), Immediate(kSmiTagMask));
862 dest->true_target()->Branch(zero); 862 dest->true_target()->Branch(zero);
863 __ fldz(); 863 __ fldz();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 925
926 // Test if operands are smi or number objects (fp). Requirements: 926 // Test if operands are smi or number objects (fp). Requirements:
927 // operand_1 in eax, operand_2 in edx; falls through on float 927 // operand_1 in eax, operand_2 in edx; falls through on float
928 // operands, jumps to the non_float label otherwise. 928 // operands, jumps to the non_float label otherwise.
929 static void CheckFloatOperands(MacroAssembler* masm, 929 static void CheckFloatOperands(MacroAssembler* masm,
930 Label* non_float, 930 Label* non_float,
931 Register scratch); 931 Register scratch);
932 // Takes the operands in edx and eax and loads them as integers in eax 932 // Takes the operands in edx and eax and loads them as integers in eax
933 // and ecx. 933 // and ecx.
934 static void LoadAsIntegers(MacroAssembler* masm, 934 static void LoadAsIntegers(MacroAssembler* masm,
935 NumberInfo number_info, 935 TypeInfo type_info,
936 bool use_sse3, 936 bool use_sse3,
937 Label* operand_conversion_failure); 937 Label* operand_conversion_failure);
938 static void LoadNumbersAsIntegers(MacroAssembler* masm, 938 static void LoadNumbersAsIntegers(MacroAssembler* masm,
939 NumberInfo number_info, 939 TypeInfo type_info,
940 bool use_sse3, 940 bool use_sse3,
941 Label* operand_conversion_failure); 941 Label* operand_conversion_failure);
942 static void LoadUnknownsAsIntegers(MacroAssembler* masm, 942 static void LoadUnknownsAsIntegers(MacroAssembler* masm,
943 bool use_sse3, 943 bool use_sse3,
944 Label* operand_conversion_failure); 944 Label* operand_conversion_failure);
945 945
946 // Test if operands are smis or heap numbers and load them 946 // Test if operands are smis or heap numbers and load them
947 // into xmm0 and xmm1 if they are. Operands are in edx and eax. 947 // into xmm0 and xmm1 if they are. Operands are in edx and eax.
948 // Leaves operands unchanged. 948 // Leaves operands unchanged.
949 static void LoadSSE2Operands(MacroAssembler* masm); 949 static void LoadSSE2Operands(MacroAssembler* masm);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 } 986 }
987 987
988 988
989 // Call the specialized stub for a binary operation. 989 // Call the specialized stub for a binary operation.
990 class DeferredInlineBinaryOperation: public DeferredCode { 990 class DeferredInlineBinaryOperation: public DeferredCode {
991 public: 991 public:
992 DeferredInlineBinaryOperation(Token::Value op, 992 DeferredInlineBinaryOperation(Token::Value op,
993 Register dst, 993 Register dst,
994 Register left, 994 Register left,
995 Register right, 995 Register right,
996 NumberInfo left_info, 996 TypeInfo left_info,
997 NumberInfo right_info, 997 TypeInfo right_info,
998 OverwriteMode mode) 998 OverwriteMode mode)
999 : op_(op), dst_(dst), left_(left), right_(right), 999 : op_(op), dst_(dst), left_(left), right_(right),
1000 left_info_(left_info), right_info_(right_info), mode_(mode) { 1000 left_info_(left_info), right_info_(right_info), mode_(mode) {
1001 set_comment("[ DeferredInlineBinaryOperation"); 1001 set_comment("[ DeferredInlineBinaryOperation");
1002 } 1002 }
1003 1003
1004 virtual void Generate(); 1004 virtual void Generate();
1005 1005
1006 private: 1006 private:
1007 Token::Value op_; 1007 Token::Value op_;
1008 Register dst_; 1008 Register dst_;
1009 Register left_; 1009 Register left_;
1010 Register right_; 1010 Register right_;
1011 NumberInfo left_info_; 1011 TypeInfo left_info_;
1012 NumberInfo right_info_; 1012 TypeInfo right_info_;
1013 OverwriteMode mode_; 1013 OverwriteMode mode_;
1014 }; 1014 };
1015 1015
1016 1016
1017 void DeferredInlineBinaryOperation::Generate() { 1017 void DeferredInlineBinaryOperation::Generate() {
1018 Label done; 1018 Label done;
1019 if (CpuFeatures::IsSupported(SSE2) && ((op_ == Token::ADD) || 1019 if (CpuFeatures::IsSupported(SSE2) && ((op_ == Token::ADD) ||
1020 (op_ ==Token::SUB) || 1020 (op_ ==Token::SUB) ||
1021 (op_ == Token::MUL) || 1021 (op_ == Token::MUL) ||
1022 (op_ == Token::DIV))) { 1022 (op_ == Token::DIV))) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 __ movdbl(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0); 1096 __ movdbl(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0);
1097 __ jmp(&done); 1097 __ jmp(&done);
1098 1098
1099 __ bind(&after_alloc_failure); 1099 __ bind(&after_alloc_failure);
1100 __ pop(left_); 1100 __ pop(left_);
1101 __ bind(&call_runtime); 1101 __ bind(&call_runtime);
1102 } 1102 }
1103 GenericBinaryOpStub stub(op_, 1103 GenericBinaryOpStub stub(op_,
1104 mode_, 1104 mode_,
1105 NO_SMI_CODE_IN_STUB, 1105 NO_SMI_CODE_IN_STUB,
1106 NumberInfo::Combine(left_info_, right_info_)); 1106 TypeInfo::Combine(left_info_, right_info_));
1107 stub.GenerateCall(masm_, left_, right_); 1107 stub.GenerateCall(masm_, left_, right_);
1108 if (!dst_.is(eax)) __ mov(dst_, eax); 1108 if (!dst_.is(eax)) __ mov(dst_, eax);
1109 __ bind(&done); 1109 __ bind(&done);
1110 } 1110 }
1111 1111
1112 1112
1113 static NumberInfo CalculateNumberInfo(NumberInfo operands_type, 1113 static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
1114 Token::Value op, 1114 Token::Value op,
1115 const Result& right, 1115 const Result& right,
1116 const Result& left) { 1116 const Result& left) {
1117 // Set NumberInfo of result according to the operation performed. 1117 // Set TypeInfo of result according to the operation performed.
1118 // Rely on the fact that smis have a 31 bit payload on ia32. 1118 // Rely on the fact that smis have a 31 bit payload on ia32.
1119 ASSERT(kSmiValueSize == 31); 1119 ASSERT(kSmiValueSize == 31);
1120 switch (op) { 1120 switch (op) {
1121 case Token::COMMA: 1121 case Token::COMMA:
1122 return right.number_info(); 1122 return right.type_info();
1123 case Token::OR: 1123 case Token::OR:
1124 case Token::AND: 1124 case Token::AND:
1125 // Result type can be either of the two input types. 1125 // Result type can be either of the two input types.
1126 return operands_type; 1126 return operands_type;
1127 case Token::BIT_AND: { 1127 case Token::BIT_AND: {
1128 // Anding with positive Smis will give you a Smi. 1128 // Anding with positive Smis will give you a Smi.
1129 if (right.is_constant() && right.handle()->IsSmi() && 1129 if (right.is_constant() && right.handle()->IsSmi() &&
1130 Smi::cast(*right.handle())->value() >= 0) { 1130 Smi::cast(*right.handle())->value() >= 0) {
1131 return NumberInfo::Smi(); 1131 return TypeInfo::Smi();
1132 } else if (left.is_constant() && left.handle()->IsSmi() && 1132 } else if (left.is_constant() && left.handle()->IsSmi() &&
1133 Smi::cast(*left.handle())->value() >= 0) { 1133 Smi::cast(*left.handle())->value() >= 0) {
1134 return NumberInfo::Smi(); 1134 return TypeInfo::Smi();
1135 } 1135 }
1136 return (operands_type.IsSmi()) 1136 return (operands_type.IsSmi())
1137 ? NumberInfo::Smi() 1137 ? TypeInfo::Smi()
1138 : NumberInfo::Integer32(); 1138 : TypeInfo::Integer32();
1139 } 1139 }
1140 case Token::BIT_OR: { 1140 case Token::BIT_OR: {
1141 // Oring with negative Smis will give you a Smi. 1141 // Oring with negative Smis will give you a Smi.
1142 if (right.is_constant() && right.handle()->IsSmi() && 1142 if (right.is_constant() && right.handle()->IsSmi() &&
1143 Smi::cast(*right.handle())->value() < 0) { 1143 Smi::cast(*right.handle())->value() < 0) {
1144 return NumberInfo::Smi(); 1144 return TypeInfo::Smi();
1145 } else if (left.is_constant() && left.handle()->IsSmi() && 1145 } else if (left.is_constant() && left.handle()->IsSmi() &&
1146 Smi::cast(*left.handle())->value() < 0) { 1146 Smi::cast(*left.handle())->value() < 0) {
1147 return NumberInfo::Smi(); 1147 return TypeInfo::Smi();
1148 } 1148 }
1149 return (operands_type.IsSmi()) 1149 return (operands_type.IsSmi())
1150 ? NumberInfo::Smi() 1150 ? TypeInfo::Smi()
1151 : NumberInfo::Integer32(); 1151 : TypeInfo::Integer32();
1152 } 1152 }
1153 case Token::BIT_XOR: 1153 case Token::BIT_XOR:
1154 // Result is always a 32 bit integer. Smi property of inputs is preserved. 1154 // Result is always a 32 bit integer. Smi property of inputs is preserved.
1155 return (operands_type.IsSmi()) 1155 return (operands_type.IsSmi())
1156 ? NumberInfo::Smi() 1156 ? TypeInfo::Smi()
1157 : NumberInfo::Integer32(); 1157 : TypeInfo::Integer32();
1158 case Token::SAR: 1158 case Token::SAR:
1159 if (left.is_smi()) return NumberInfo::Smi(); 1159 if (left.is_smi()) return TypeInfo::Smi();
1160 // Result is a smi if we shift by a constant >= 1, otherwise an integer32. 1160 // Result is a smi if we shift by a constant >= 1, otherwise an integer32.
1161 return (right.is_constant() && right.handle()->IsSmi() 1161 return (right.is_constant() && right.handle()->IsSmi()
1162 && Smi::cast(*right.handle())->value() >= 1) 1162 && Smi::cast(*right.handle())->value() >= 1)
1163 ? NumberInfo::Smi() 1163 ? TypeInfo::Smi()
1164 : NumberInfo::Integer32(); 1164 : TypeInfo::Integer32();
1165 case Token::SHR: 1165 case Token::SHR:
1166 // Result is a smi if we shift by a constant >= 2, otherwise an integer32. 1166 // Result is a smi if we shift by a constant >= 2, otherwise an integer32.
1167 return (right.is_constant() && right.handle()->IsSmi() 1167 return (right.is_constant() && right.handle()->IsSmi()
1168 && Smi::cast(*right.handle())->value() >= 2) 1168 && Smi::cast(*right.handle())->value() >= 2)
1169 ? NumberInfo::Smi() 1169 ? TypeInfo::Smi()
1170 : NumberInfo::Integer32(); 1170 : TypeInfo::Integer32();
1171 case Token::ADD: 1171 case Token::ADD:
1172 if (operands_type.IsSmi()) { 1172 if (operands_type.IsSmi()) {
1173 // The Integer32 range is big enough to take the sum of any two Smis. 1173 // The Integer32 range is big enough to take the sum of any two Smis.
1174 return NumberInfo::Integer32(); 1174 return TypeInfo::Integer32();
1175 } else { 1175 } else {
1176 // Result could be a string or a number. Check types of inputs. 1176 // Result could be a string or a number. Check types of inputs.
1177 return operands_type.IsNumber() 1177 return operands_type.IsNumber()
1178 ? NumberInfo::Number() 1178 ? TypeInfo::Number()
1179 : NumberInfo::Unknown(); 1179 : TypeInfo::Unknown();
1180 } 1180 }
1181 case Token::SHL: 1181 case Token::SHL:
1182 return NumberInfo::Integer32(); 1182 return TypeInfo::Integer32();
1183 case Token::SUB: 1183 case Token::SUB:
1184 // The Integer32 range is big enough to take the difference of any two 1184 // The Integer32 range is big enough to take the difference of any two
1185 // Smis. 1185 // Smis.
1186 return (operands_type.IsSmi()) ? 1186 return (operands_type.IsSmi()) ?
1187 NumberInfo::Integer32() : 1187 TypeInfo::Integer32() :
1188 NumberInfo::Number(); 1188 TypeInfo::Number();
1189 case Token::MUL: 1189 case Token::MUL:
1190 case Token::DIV: 1190 case Token::DIV:
1191 case Token::MOD: 1191 case Token::MOD:
1192 // Result is always a number. 1192 // Result is always a number.
1193 return NumberInfo::Number(); 1193 return TypeInfo::Number();
1194 default: 1194 default:
1195 UNREACHABLE(); 1195 UNREACHABLE();
1196 } 1196 }
1197 UNREACHABLE(); 1197 UNREACHABLE();
1198 return NumberInfo::Unknown(); 1198 return TypeInfo::Unknown();
1199 } 1199 }
1200 1200
1201 1201
1202 void CodeGenerator::GenericBinaryOperation(Token::Value op, 1202 void CodeGenerator::GenericBinaryOperation(Token::Value op,
1203 StaticType* type, 1203 StaticType* type,
1204 OverwriteMode overwrite_mode, 1204 OverwriteMode overwrite_mode,
1205 bool no_negative_zero) { 1205 bool no_negative_zero) {
1206 Comment cmnt(masm_, "[ BinaryOperation"); 1206 Comment cmnt(masm_, "[ BinaryOperation");
1207 Comment cmnt_token(masm_, Token::String(op)); 1207 Comment cmnt_token(masm_, Token::String(op));
1208 1208
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 right.is_constant() && !right.handle()->IsSmi(); 1248 right.is_constant() && !right.handle()->IsSmi();
1249 1249
1250 if (left_is_smi_constant && right_is_smi_constant) { 1250 if (left_is_smi_constant && right_is_smi_constant) {
1251 // Compute the constant result at compile time, and leave it on the frame. 1251 // Compute the constant result at compile time, and leave it on the frame.
1252 int left_int = Smi::cast(*left.handle())->value(); 1252 int left_int = Smi::cast(*left.handle())->value();
1253 int right_int = Smi::cast(*right.handle())->value(); 1253 int right_int = Smi::cast(*right.handle())->value();
1254 if (FoldConstantSmis(op, left_int, right_int)) return; 1254 if (FoldConstantSmis(op, left_int, right_int)) return;
1255 } 1255 }
1256 1256
1257 // Get number type of left and right sub-expressions. 1257 // Get number type of left and right sub-expressions.
1258 NumberInfo operands_type = 1258 TypeInfo operands_type =
1259 NumberInfo::Combine(left.number_info(), right.number_info()); 1259 TypeInfo::Combine(left.type_info(), right.type_info());
1260 1260
1261 NumberInfo result_type = CalculateNumberInfo(operands_type, op, right, left); 1261 TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left);
1262 1262
1263 Result answer; 1263 Result answer;
1264 if (left_is_non_smi_constant || right_is_non_smi_constant) { 1264 if (left_is_non_smi_constant || right_is_non_smi_constant) {
1265 // Go straight to the slow case, with no smi code. 1265 // Go straight to the slow case, with no smi code.
1266 GenericBinaryOpStub stub(op, 1266 GenericBinaryOpStub stub(op,
1267 overwrite_mode, 1267 overwrite_mode,
1268 NO_SMI_CODE_IN_STUB, 1268 NO_SMI_CODE_IN_STUB,
1269 operands_type); 1269 operands_type);
1270 answer = stub.GenerateCall(masm_, frame_, &left, &right); 1270 answer = stub.GenerateCall(masm_, frame_, &left, &right);
1271 } else if (right_is_smi_constant) { 1271 } else if (right_is_smi_constant) {
(...skipping 18 matching lines...) Expand all
1290 overwrite_mode, no_negative_zero); 1290 overwrite_mode, no_negative_zero);
1291 } else { 1291 } else {
1292 GenericBinaryOpStub stub(op, 1292 GenericBinaryOpStub stub(op,
1293 overwrite_mode, 1293 overwrite_mode,
1294 NO_GENERIC_BINARY_FLAGS, 1294 NO_GENERIC_BINARY_FLAGS,
1295 operands_type); 1295 operands_type);
1296 answer = stub.GenerateCall(masm_, frame_, &left, &right); 1296 answer = stub.GenerateCall(masm_, frame_, &left, &right);
1297 } 1297 }
1298 } 1298 }
1299 1299
1300 answer.set_number_info(result_type); 1300 answer.set_type_info(result_type);
1301 frame_->Push(&answer); 1301 frame_->Push(&answer);
1302 } 1302 }
1303 1303
1304 1304
1305 bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) { 1305 bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) {
1306 Object* answer_object = Heap::undefined_value(); 1306 Object* answer_object = Heap::undefined_value();
1307 switch (op) { 1307 switch (op) {
1308 case Token::ADD: 1308 case Token::ADD:
1309 if (Smi::IsValid(left + right)) { 1309 if (Smi::IsValid(left + right)) {
1310 answer_object = Smi::FromInt(left + right); 1310 answer_object = Smi::FromInt(left + right);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 if (answer_object == Heap::undefined_value()) { 1378 if (answer_object == Heap::undefined_value()) {
1379 return false; 1379 return false;
1380 } 1380 }
1381 frame_->Push(Handle<Object>(answer_object)); 1381 frame_->Push(Handle<Object>(answer_object));
1382 return true; 1382 return true;
1383 } 1383 }
1384 1384
1385 1385
1386 static void CheckTwoForSminess(MacroAssembler* masm, 1386 static void CheckTwoForSminess(MacroAssembler* masm,
1387 Register left, Register right, Register scratch, 1387 Register left, Register right, Register scratch,
1388 NumberInfo left_info, NumberInfo right_info, 1388 TypeInfo left_info, TypeInfo right_info,
1389 DeferredInlineBinaryOperation* deferred); 1389 DeferredInlineBinaryOperation* deferred);
1390 1390
1391 1391
1392 // Implements a binary operation using a deferred code object and some 1392 // Implements a binary operation using a deferred code object and some
1393 // inline code to operate on smis quickly. 1393 // inline code to operate on smis quickly.
1394 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 1394 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
1395 Result* left, 1395 Result* left,
1396 Result* right, 1396 Result* right,
1397 OverwriteMode overwrite_mode, 1397 OverwriteMode overwrite_mode,
1398 bool no_negative_zero) { 1398 bool no_negative_zero) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 right->ToRegister(); 1463 right->ToRegister();
1464 frame_->Spill(eax); 1464 frame_->Spill(eax);
1465 frame_->Spill(edx); 1465 frame_->Spill(edx);
1466 1466
1467 // Check that left and right are smi tagged. 1467 // Check that left and right are smi tagged.
1468 DeferredInlineBinaryOperation* deferred = 1468 DeferredInlineBinaryOperation* deferred =
1469 new DeferredInlineBinaryOperation(op, 1469 new DeferredInlineBinaryOperation(op,
1470 (op == Token::DIV) ? eax : edx, 1470 (op == Token::DIV) ? eax : edx,
1471 left->reg(), 1471 left->reg(),
1472 right->reg(), 1472 right->reg(),
1473 left->number_info(), 1473 left->type_info(),
1474 right->number_info(), 1474 right->type_info(),
1475 overwrite_mode); 1475 overwrite_mode);
1476 if (left->reg().is(right->reg())) { 1476 if (left->reg().is(right->reg())) {
1477 __ test(left->reg(), Immediate(kSmiTagMask)); 1477 __ test(left->reg(), Immediate(kSmiTagMask));
1478 } else { 1478 } else {
1479 // Use the quotient register as a scratch for the tag check. 1479 // Use the quotient register as a scratch for the tag check.
1480 if (!left_is_in_eax) __ mov(eax, left->reg()); 1480 if (!left_is_in_eax) __ mov(eax, left->reg());
1481 left_is_in_eax = false; // About to destroy the value in eax. 1481 left_is_in_eax = false; // About to destroy the value in eax.
1482 __ or_(eax, Operand(right->reg())); 1482 __ or_(eax, Operand(right->reg()));
1483 ASSERT(kSmiTag == 0); // Adjust test if not the case. 1483 ASSERT(kSmiTag == 0); // Adjust test if not the case.
1484 __ test(eax, Immediate(kSmiTagMask)); 1484 __ test(eax, Immediate(kSmiTagMask));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 // Use a fresh answer register to avoid spilling the left operand. 1567 // Use a fresh answer register to avoid spilling the left operand.
1568 answer = allocator_->Allocate(); 1568 answer = allocator_->Allocate();
1569 ASSERT(answer.is_valid()); 1569 ASSERT(answer.is_valid());
1570 // Check that both operands are smis using the answer register as a 1570 // Check that both operands are smis using the answer register as a
1571 // temporary. 1571 // temporary.
1572 DeferredInlineBinaryOperation* deferred = 1572 DeferredInlineBinaryOperation* deferred =
1573 new DeferredInlineBinaryOperation(op, 1573 new DeferredInlineBinaryOperation(op,
1574 answer.reg(), 1574 answer.reg(),
1575 left->reg(), 1575 left->reg(),
1576 ecx, 1576 ecx,
1577 left->number_info(), 1577 left->type_info(),
1578 right->number_info(), 1578 right->type_info(),
1579 overwrite_mode); 1579 overwrite_mode);
1580 1580
1581 Label do_op, left_nonsmi; 1581 Label do_op, left_nonsmi;
1582 // If right is a smi we make a fast case if left is either a smi 1582 // If right is a smi we make a fast case if left is either a smi
1583 // or a heapnumber. 1583 // or a heapnumber.
1584 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { 1584 if (CpuFeatures::IsSupported(SSE2) && right->type_info().IsSmi()) {
1585 CpuFeatures::Scope use_sse2(SSE2); 1585 CpuFeatures::Scope use_sse2(SSE2);
1586 __ mov(answer.reg(), left->reg()); 1586 __ mov(answer.reg(), left->reg());
1587 // Fast case - both are actually smis. 1587 // Fast case - both are actually smis.
1588 if (!left->number_info().IsSmi()) { 1588 if (!left->type_info().IsSmi()) {
1589 __ test(answer.reg(), Immediate(kSmiTagMask)); 1589 __ test(answer.reg(), Immediate(kSmiTagMask));
1590 __ j(not_zero, &left_nonsmi); 1590 __ j(not_zero, &left_nonsmi);
1591 } else { 1591 } else {
1592 if (FLAG_debug_code) __ AbortIfNotSmi(left->reg()); 1592 if (FLAG_debug_code) __ AbortIfNotSmi(left->reg());
1593 } 1593 }
1594 if (FLAG_debug_code) __ AbortIfNotSmi(right->reg()); 1594 if (FLAG_debug_code) __ AbortIfNotSmi(right->reg());
1595 __ SmiUntag(answer.reg()); 1595 __ SmiUntag(answer.reg());
1596 __ jmp(&do_op); 1596 __ jmp(&do_op);
1597 1597
1598 __ bind(&left_nonsmi); 1598 __ bind(&left_nonsmi);
1599 // Branch if not a heapnumber. 1599 // Branch if not a heapnumber.
1600 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), 1600 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset),
1601 Factory::heap_number_map()); 1601 Factory::heap_number_map());
1602 deferred->Branch(not_equal); 1602 deferred->Branch(not_equal);
1603 1603
1604 // Load integer value into answer register using truncation. 1604 // Load integer value into answer register using truncation.
1605 __ cvttsd2si(answer.reg(), 1605 __ cvttsd2si(answer.reg(),
1606 FieldOperand(answer.reg(), HeapNumber::kValueOffset)); 1606 FieldOperand(answer.reg(), HeapNumber::kValueOffset));
1607 // Branch if we do not fit in a smi. 1607 // Branch if we do not fit in a smi.
1608 __ cmp(answer.reg(), 0xc0000000); 1608 __ cmp(answer.reg(), 0xc0000000);
1609 deferred->Branch(negative); 1609 deferred->Branch(negative);
1610 } else { 1610 } else {
1611 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), 1611 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
1612 left->number_info(), right->number_info(), deferred); 1612 left->type_info(), right->type_info(), deferred);
1613 1613
1614 // Untag both operands. 1614 // Untag both operands.
1615 __ mov(answer.reg(), left->reg()); 1615 __ mov(answer.reg(), left->reg());
1616 __ SmiUntag(answer.reg()); 1616 __ SmiUntag(answer.reg());
1617 } 1617 }
1618 1618
1619 __ bind(&do_op); 1619 __ bind(&do_op);
1620 __ SmiUntag(ecx); 1620 __ SmiUntag(ecx);
1621 // Perform the operation. 1621 // Perform the operation.
1622 switch (op) { 1622 switch (op) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 // need to be spilled in the fast case. 1675 // need to be spilled in the fast case.
1676 answer = allocator_->Allocate(); 1676 answer = allocator_->Allocate();
1677 ASSERT(answer.is_valid()); 1677 ASSERT(answer.is_valid());
1678 1678
1679 // Perform the smi tag check. 1679 // Perform the smi tag check.
1680 DeferredInlineBinaryOperation* deferred = 1680 DeferredInlineBinaryOperation* deferred =
1681 new DeferredInlineBinaryOperation(op, 1681 new DeferredInlineBinaryOperation(op,
1682 answer.reg(), 1682 answer.reg(),
1683 left->reg(), 1683 left->reg(),
1684 right->reg(), 1684 right->reg(),
1685 left->number_info(), 1685 left->type_info(),
1686 right->number_info(), 1686 right->type_info(),
1687 overwrite_mode); 1687 overwrite_mode);
1688 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), 1688 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
1689 left->number_info(), right->number_info(), deferred); 1689 left->type_info(), right->type_info(), deferred);
1690 1690
1691 __ mov(answer.reg(), left->reg()); 1691 __ mov(answer.reg(), left->reg());
1692 switch (op) { 1692 switch (op) {
1693 case Token::ADD: 1693 case Token::ADD:
1694 __ add(answer.reg(), Operand(right->reg())); 1694 __ add(answer.reg(), Operand(right->reg()));
1695 deferred->Branch(overflow); 1695 deferred->Branch(overflow);
1696 break; 1696 break;
1697 1697
1698 case Token::SUB: 1698 case Token::SUB:
1699 __ sub(answer.reg(), Operand(right->reg())); 1699 __ sub(answer.reg(), Operand(right->reg()));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 } 1751 }
1752 1752
1753 1753
1754 // Call the appropriate binary operation stub to compute src op value 1754 // Call the appropriate binary operation stub to compute src op value
1755 // and leave the result in dst. 1755 // and leave the result in dst.
1756 class DeferredInlineSmiOperation: public DeferredCode { 1756 class DeferredInlineSmiOperation: public DeferredCode {
1757 public: 1757 public:
1758 DeferredInlineSmiOperation(Token::Value op, 1758 DeferredInlineSmiOperation(Token::Value op,
1759 Register dst, 1759 Register dst,
1760 Register src, 1760 Register src,
1761 NumberInfo number_info, 1761 TypeInfo type_info,
1762 Smi* value, 1762 Smi* value,
1763 OverwriteMode overwrite_mode) 1763 OverwriteMode overwrite_mode)
1764 : op_(op), 1764 : op_(op),
1765 dst_(dst), 1765 dst_(dst),
1766 src_(src), 1766 src_(src),
1767 number_info_(number_info), 1767 type_info_(type_info),
1768 value_(value), 1768 value_(value),
1769 overwrite_mode_(overwrite_mode) { 1769 overwrite_mode_(overwrite_mode) {
1770 if (number_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE; 1770 if (type_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
1771 set_comment("[ DeferredInlineSmiOperation"); 1771 set_comment("[ DeferredInlineSmiOperation");
1772 } 1772 }
1773 1773
1774 virtual void Generate(); 1774 virtual void Generate();
1775 1775
1776 private: 1776 private:
1777 Token::Value op_; 1777 Token::Value op_;
1778 Register dst_; 1778 Register dst_;
1779 Register src_; 1779 Register src_;
1780 NumberInfo number_info_; 1780 TypeInfo type_info_;
1781 Smi* value_; 1781 Smi* value_;
1782 OverwriteMode overwrite_mode_; 1782 OverwriteMode overwrite_mode_;
1783 }; 1783 };
1784 1784
1785 1785
1786 void DeferredInlineSmiOperation::Generate() { 1786 void DeferredInlineSmiOperation::Generate() {
1787 // For mod we don't generate all the Smi code inline. 1787 // For mod we don't generate all the Smi code inline.
1788 GenericBinaryOpStub stub( 1788 GenericBinaryOpStub stub(
1789 op_, 1789 op_,
1790 overwrite_mode_, 1790 overwrite_mode_,
1791 (op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB, 1791 (op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB,
1792 NumberInfo::Combine(NumberInfo::Smi(), number_info_)); 1792 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1793 stub.GenerateCall(masm_, src_, value_); 1793 stub.GenerateCall(masm_, src_, value_);
1794 if (!dst_.is(eax)) __ mov(dst_, eax); 1794 if (!dst_.is(eax)) __ mov(dst_, eax);
1795 } 1795 }
1796 1796
1797 1797
1798 // Call the appropriate binary operation stub to compute value op src 1798 // Call the appropriate binary operation stub to compute value op src
1799 // and leave the result in dst. 1799 // and leave the result in dst.
1800 class DeferredInlineSmiOperationReversed: public DeferredCode { 1800 class DeferredInlineSmiOperationReversed: public DeferredCode {
1801 public: 1801 public:
1802 DeferredInlineSmiOperationReversed(Token::Value op, 1802 DeferredInlineSmiOperationReversed(Token::Value op,
1803 Register dst, 1803 Register dst,
1804 Smi* value, 1804 Smi* value,
1805 Register src, 1805 Register src,
1806 NumberInfo number_info, 1806 TypeInfo type_info,
1807 OverwriteMode overwrite_mode) 1807 OverwriteMode overwrite_mode)
1808 : op_(op), 1808 : op_(op),
1809 dst_(dst), 1809 dst_(dst),
1810 number_info_(number_info), 1810 type_info_(type_info),
1811 value_(value), 1811 value_(value),
1812 src_(src), 1812 src_(src),
1813 overwrite_mode_(overwrite_mode) { 1813 overwrite_mode_(overwrite_mode) {
1814 set_comment("[ DeferredInlineSmiOperationReversed"); 1814 set_comment("[ DeferredInlineSmiOperationReversed");
1815 } 1815 }
1816 1816
1817 virtual void Generate(); 1817 virtual void Generate();
1818 1818
1819 private: 1819 private:
1820 Token::Value op_; 1820 Token::Value op_;
1821 Register dst_; 1821 Register dst_;
1822 NumberInfo number_info_; 1822 TypeInfo type_info_;
1823 Smi* value_; 1823 Smi* value_;
1824 Register src_; 1824 Register src_;
1825 OverwriteMode overwrite_mode_; 1825 OverwriteMode overwrite_mode_;
1826 }; 1826 };
1827 1827
1828 1828
1829 void DeferredInlineSmiOperationReversed::Generate() { 1829 void DeferredInlineSmiOperationReversed::Generate() {
1830 GenericBinaryOpStub igostub( 1830 GenericBinaryOpStub igostub(
1831 op_, 1831 op_,
1832 overwrite_mode_, 1832 overwrite_mode_,
1833 NO_SMI_CODE_IN_STUB, 1833 NO_SMI_CODE_IN_STUB,
1834 NumberInfo::Combine(NumberInfo::Smi(), number_info_)); 1834 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1835 igostub.GenerateCall(masm_, value_, src_); 1835 igostub.GenerateCall(masm_, value_, src_);
1836 if (!dst_.is(eax)) __ mov(dst_, eax); 1836 if (!dst_.is(eax)) __ mov(dst_, eax);
1837 } 1837 }
1838 1838
1839 1839
1840 // The result of src + value is in dst. It either overflowed or was not 1840 // The result of src + value is in dst. It either overflowed or was not
1841 // smi tagged. Undo the speculative addition and call the appropriate 1841 // smi tagged. Undo the speculative addition and call the appropriate
1842 // specialized stub for add. The result is left in dst. 1842 // specialized stub for add. The result is left in dst.
1843 class DeferredInlineSmiAdd: public DeferredCode { 1843 class DeferredInlineSmiAdd: public DeferredCode {
1844 public: 1844 public:
1845 DeferredInlineSmiAdd(Register dst, 1845 DeferredInlineSmiAdd(Register dst,
1846 NumberInfo number_info, 1846 TypeInfo type_info,
1847 Smi* value, 1847 Smi* value,
1848 OverwriteMode overwrite_mode) 1848 OverwriteMode overwrite_mode)
1849 : dst_(dst), 1849 : dst_(dst),
1850 number_info_(number_info), 1850 type_info_(type_info),
1851 value_(value), 1851 value_(value),
1852 overwrite_mode_(overwrite_mode) { 1852 overwrite_mode_(overwrite_mode) {
1853 if (number_info_.IsSmi()) overwrite_mode_ = NO_OVERWRITE; 1853 if (type_info_.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
1854 set_comment("[ DeferredInlineSmiAdd"); 1854 set_comment("[ DeferredInlineSmiAdd");
1855 } 1855 }
1856 1856
1857 virtual void Generate(); 1857 virtual void Generate();
1858 1858
1859 private: 1859 private:
1860 Register dst_; 1860 Register dst_;
1861 NumberInfo number_info_; 1861 TypeInfo type_info_;
1862 Smi* value_; 1862 Smi* value_;
1863 OverwriteMode overwrite_mode_; 1863 OverwriteMode overwrite_mode_;
1864 }; 1864 };
1865 1865
1866 1866
1867 void DeferredInlineSmiAdd::Generate() { 1867 void DeferredInlineSmiAdd::Generate() {
1868 // Undo the optimistic add operation and call the shared stub. 1868 // Undo the optimistic add operation and call the shared stub.
1869 __ sub(Operand(dst_), Immediate(value_)); 1869 __ sub(Operand(dst_), Immediate(value_));
1870 GenericBinaryOpStub igostub( 1870 GenericBinaryOpStub igostub(
1871 Token::ADD, 1871 Token::ADD,
1872 overwrite_mode_, 1872 overwrite_mode_,
1873 NO_SMI_CODE_IN_STUB, 1873 NO_SMI_CODE_IN_STUB,
1874 NumberInfo::Combine(NumberInfo::Smi(), number_info_)); 1874 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1875 igostub.GenerateCall(masm_, dst_, value_); 1875 igostub.GenerateCall(masm_, dst_, value_);
1876 if (!dst_.is(eax)) __ mov(dst_, eax); 1876 if (!dst_.is(eax)) __ mov(dst_, eax);
1877 } 1877 }
1878 1878
1879 1879
1880 // The result of value + src is in dst. It either overflowed or was not 1880 // The result of value + src is in dst. It either overflowed or was not
1881 // smi tagged. Undo the speculative addition and call the appropriate 1881 // smi tagged. Undo the speculative addition and call the appropriate
1882 // specialized stub for add. The result is left in dst. 1882 // specialized stub for add. The result is left in dst.
1883 class DeferredInlineSmiAddReversed: public DeferredCode { 1883 class DeferredInlineSmiAddReversed: public DeferredCode {
1884 public: 1884 public:
1885 DeferredInlineSmiAddReversed(Register dst, 1885 DeferredInlineSmiAddReversed(Register dst,
1886 NumberInfo number_info, 1886 TypeInfo type_info,
1887 Smi* value, 1887 Smi* value,
1888 OverwriteMode overwrite_mode) 1888 OverwriteMode overwrite_mode)
1889 : dst_(dst), 1889 : dst_(dst),
1890 number_info_(number_info), 1890 type_info_(type_info),
1891 value_(value), 1891 value_(value),
1892 overwrite_mode_(overwrite_mode) { 1892 overwrite_mode_(overwrite_mode) {
1893 set_comment("[ DeferredInlineSmiAddReversed"); 1893 set_comment("[ DeferredInlineSmiAddReversed");
1894 } 1894 }
1895 1895
1896 virtual void Generate(); 1896 virtual void Generate();
1897 1897
1898 private: 1898 private:
1899 Register dst_; 1899 Register dst_;
1900 NumberInfo number_info_; 1900 TypeInfo type_info_;
1901 Smi* value_; 1901 Smi* value_;
1902 OverwriteMode overwrite_mode_; 1902 OverwriteMode overwrite_mode_;
1903 }; 1903 };
1904 1904
1905 1905
1906 void DeferredInlineSmiAddReversed::Generate() { 1906 void DeferredInlineSmiAddReversed::Generate() {
1907 // Undo the optimistic add operation and call the shared stub. 1907 // Undo the optimistic add operation and call the shared stub.
1908 __ sub(Operand(dst_), Immediate(value_)); 1908 __ sub(Operand(dst_), Immediate(value_));
1909 GenericBinaryOpStub igostub( 1909 GenericBinaryOpStub igostub(
1910 Token::ADD, 1910 Token::ADD,
1911 overwrite_mode_, 1911 overwrite_mode_,
1912 NO_SMI_CODE_IN_STUB, 1912 NO_SMI_CODE_IN_STUB,
1913 NumberInfo::Combine(NumberInfo::Smi(), number_info_)); 1913 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1914 igostub.GenerateCall(masm_, value_, dst_); 1914 igostub.GenerateCall(masm_, value_, dst_);
1915 if (!dst_.is(eax)) __ mov(dst_, eax); 1915 if (!dst_.is(eax)) __ mov(dst_, eax);
1916 } 1916 }
1917 1917
1918 1918
1919 // The result of src - value is in dst. It either overflowed or was not 1919 // The result of src - value is in dst. It either overflowed or was not
1920 // smi tagged. Undo the speculative subtraction and call the 1920 // smi tagged. Undo the speculative subtraction and call the
1921 // appropriate specialized stub for subtract. The result is left in 1921 // appropriate specialized stub for subtract. The result is left in
1922 // dst. 1922 // dst.
1923 class DeferredInlineSmiSub: public DeferredCode { 1923 class DeferredInlineSmiSub: public DeferredCode {
1924 public: 1924 public:
1925 DeferredInlineSmiSub(Register dst, 1925 DeferredInlineSmiSub(Register dst,
1926 NumberInfo number_info, 1926 TypeInfo type_info,
1927 Smi* value, 1927 Smi* value,
1928 OverwriteMode overwrite_mode) 1928 OverwriteMode overwrite_mode)
1929 : dst_(dst), 1929 : dst_(dst),
1930 number_info_(number_info), 1930 type_info_(type_info),
1931 value_(value), 1931 value_(value),
1932 overwrite_mode_(overwrite_mode) { 1932 overwrite_mode_(overwrite_mode) {
1933 if (number_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE; 1933 if (type_info.IsSmi()) overwrite_mode_ = NO_OVERWRITE;
1934 set_comment("[ DeferredInlineSmiSub"); 1934 set_comment("[ DeferredInlineSmiSub");
1935 } 1935 }
1936 1936
1937 virtual void Generate(); 1937 virtual void Generate();
1938 1938
1939 private: 1939 private:
1940 Register dst_; 1940 Register dst_;
1941 NumberInfo number_info_; 1941 TypeInfo type_info_;
1942 Smi* value_; 1942 Smi* value_;
1943 OverwriteMode overwrite_mode_; 1943 OverwriteMode overwrite_mode_;
1944 }; 1944 };
1945 1945
1946 1946
1947 void DeferredInlineSmiSub::Generate() { 1947 void DeferredInlineSmiSub::Generate() {
1948 // Undo the optimistic sub operation and call the shared stub. 1948 // Undo the optimistic sub operation and call the shared stub.
1949 __ add(Operand(dst_), Immediate(value_)); 1949 __ add(Operand(dst_), Immediate(value_));
1950 GenericBinaryOpStub igostub( 1950 GenericBinaryOpStub igostub(
1951 Token::SUB, 1951 Token::SUB,
1952 overwrite_mode_, 1952 overwrite_mode_,
1953 NO_SMI_CODE_IN_STUB, 1953 NO_SMI_CODE_IN_STUB,
1954 NumberInfo::Combine(NumberInfo::Smi(), number_info_)); 1954 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1955 igostub.GenerateCall(masm_, dst_, value_); 1955 igostub.GenerateCall(masm_, dst_, value_);
1956 if (!dst_.is(eax)) __ mov(dst_, eax); 1956 if (!dst_.is(eax)) __ mov(dst_, eax);
1957 } 1957 }
1958 1958
1959 1959
1960 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 1960 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
1961 Result* operand, 1961 Result* operand,
1962 Handle<Object> value, 1962 Handle<Object> value,
1963 StaticType* type, 1963 StaticType* type,
1964 bool reversed, 1964 bool reversed,
(...skipping 24 matching lines...) Expand all
1989 switch (op) { 1989 switch (op) {
1990 case Token::ADD: { 1990 case Token::ADD: {
1991 operand->ToRegister(); 1991 operand->ToRegister();
1992 frame_->Spill(operand->reg()); 1992 frame_->Spill(operand->reg());
1993 1993
1994 // Optimistically add. Call the specialized add stub if the 1994 // Optimistically add. Call the specialized add stub if the
1995 // result is not a smi or overflows. 1995 // result is not a smi or overflows.
1996 DeferredCode* deferred = NULL; 1996 DeferredCode* deferred = NULL;
1997 if (reversed) { 1997 if (reversed) {
1998 deferred = new DeferredInlineSmiAddReversed(operand->reg(), 1998 deferred = new DeferredInlineSmiAddReversed(operand->reg(),
1999 operand->number_info(), 1999 operand->type_info(),
2000 smi_value, 2000 smi_value,
2001 overwrite_mode); 2001 overwrite_mode);
2002 } else { 2002 } else {
2003 deferred = new DeferredInlineSmiAdd(operand->reg(), 2003 deferred = new DeferredInlineSmiAdd(operand->reg(),
2004 operand->number_info(), 2004 operand->type_info(),
2005 smi_value, 2005 smi_value,
2006 overwrite_mode); 2006 overwrite_mode);
2007 } 2007 }
2008 __ add(Operand(operand->reg()), Immediate(value)); 2008 __ add(Operand(operand->reg()), Immediate(value));
2009 deferred->Branch(overflow); 2009 deferred->Branch(overflow);
2010 if (!operand->number_info().IsSmi()) { 2010 if (!operand->type_info().IsSmi()) {
2011 __ test(operand->reg(), Immediate(kSmiTagMask)); 2011 __ test(operand->reg(), Immediate(kSmiTagMask));
2012 deferred->Branch(not_zero); 2012 deferred->Branch(not_zero);
2013 } else { 2013 } else {
2014 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2014 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg());
2015 } 2015 }
2016 deferred->BindExit(); 2016 deferred->BindExit();
2017 answer = *operand; 2017 answer = *operand;
2018 break; 2018 break;
2019 } 2019 }
2020 2020
2021 case Token::SUB: { 2021 case Token::SUB: {
2022 DeferredCode* deferred = NULL; 2022 DeferredCode* deferred = NULL;
2023 if (reversed) { 2023 if (reversed) {
2024 // The reversed case is only hit when the right operand is not a 2024 // The reversed case is only hit when the right operand is not a
2025 // constant. 2025 // constant.
2026 ASSERT(operand->is_register()); 2026 ASSERT(operand->is_register());
2027 answer = allocator()->Allocate(); 2027 answer = allocator()->Allocate();
2028 ASSERT(answer.is_valid()); 2028 ASSERT(answer.is_valid());
2029 __ Set(answer.reg(), Immediate(value)); 2029 __ Set(answer.reg(), Immediate(value));
2030 deferred = 2030 deferred =
2031 new DeferredInlineSmiOperationReversed(op, 2031 new DeferredInlineSmiOperationReversed(op,
2032 answer.reg(), 2032 answer.reg(),
2033 smi_value, 2033 smi_value,
2034 operand->reg(), 2034 operand->reg(),
2035 operand->number_info(), 2035 operand->type_info(),
2036 overwrite_mode); 2036 overwrite_mode);
2037 __ sub(answer.reg(), Operand(operand->reg())); 2037 __ sub(answer.reg(), Operand(operand->reg()));
2038 } else { 2038 } else {
2039 operand->ToRegister(); 2039 operand->ToRegister();
2040 frame_->Spill(operand->reg()); 2040 frame_->Spill(operand->reg());
2041 answer = *operand; 2041 answer = *operand;
2042 deferred = new DeferredInlineSmiSub(operand->reg(), 2042 deferred = new DeferredInlineSmiSub(operand->reg(),
2043 operand->number_info(), 2043 operand->type_info(),
2044 smi_value, 2044 smi_value,
2045 overwrite_mode); 2045 overwrite_mode);
2046 __ sub(Operand(operand->reg()), Immediate(value)); 2046 __ sub(Operand(operand->reg()), Immediate(value));
2047 } 2047 }
2048 deferred->Branch(overflow); 2048 deferred->Branch(overflow);
2049 if (!operand->number_info().IsSmi()) { 2049 if (!operand->type_info().IsSmi()) {
2050 __ test(answer.reg(), Immediate(kSmiTagMask)); 2050 __ test(answer.reg(), Immediate(kSmiTagMask));
2051 deferred->Branch(not_zero); 2051 deferred->Branch(not_zero);
2052 } else { 2052 } else {
2053 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2053 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg());
2054 } 2054 }
2055 deferred->BindExit(); 2055 deferred->BindExit();
2056 operand->Unuse(); 2056 operand->Unuse();
2057 break; 2057 break;
2058 } 2058 }
2059 2059
2060 case Token::SAR: 2060 case Token::SAR:
2061 if (reversed) { 2061 if (reversed) {
2062 Result constant_operand(value); 2062 Result constant_operand(value);
2063 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2063 answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
2064 overwrite_mode, no_negative_zero); 2064 overwrite_mode, no_negative_zero);
2065 } else { 2065 } else {
2066 // Only the least significant 5 bits of the shift value are used. 2066 // Only the least significant 5 bits of the shift value are used.
2067 // In the slow case, this masking is done inside the runtime call. 2067 // In the slow case, this masking is done inside the runtime call.
2068 int shift_value = int_value & 0x1f; 2068 int shift_value = int_value & 0x1f;
2069 operand->ToRegister(); 2069 operand->ToRegister();
2070 frame_->Spill(operand->reg()); 2070 frame_->Spill(operand->reg());
2071 if (!operand->number_info().IsSmi()) { 2071 if (!operand->type_info().IsSmi()) {
2072 DeferredInlineSmiOperation* deferred = 2072 DeferredInlineSmiOperation* deferred =
2073 new DeferredInlineSmiOperation(op, 2073 new DeferredInlineSmiOperation(op,
2074 operand->reg(), 2074 operand->reg(),
2075 operand->reg(), 2075 operand->reg(),
2076 operand->number_info(), 2076 operand->type_info(),
2077 smi_value, 2077 smi_value,
2078 overwrite_mode); 2078 overwrite_mode);
2079 __ test(operand->reg(), Immediate(kSmiTagMask)); 2079 __ test(operand->reg(), Immediate(kSmiTagMask));
2080 deferred->Branch(not_zero); 2080 deferred->Branch(not_zero);
2081 if (shift_value > 0) { 2081 if (shift_value > 0) {
2082 __ sar(operand->reg(), shift_value); 2082 __ sar(operand->reg(), shift_value);
2083 __ and_(operand->reg(), ~kSmiTagMask); 2083 __ and_(operand->reg(), ~kSmiTagMask);
2084 } 2084 }
2085 deferred->BindExit(); 2085 deferred->BindExit();
2086 } else { 2086 } else {
(...skipping 16 matching lines...) Expand all
2103 // Only the least significant 5 bits of the shift value are used. 2103 // Only the least significant 5 bits of the shift value are used.
2104 // In the slow case, this masking is done inside the runtime call. 2104 // In the slow case, this masking is done inside the runtime call.
2105 int shift_value = int_value & 0x1f; 2105 int shift_value = int_value & 0x1f;
2106 operand->ToRegister(); 2106 operand->ToRegister();
2107 answer = allocator()->Allocate(); 2107 answer = allocator()->Allocate();
2108 ASSERT(answer.is_valid()); 2108 ASSERT(answer.is_valid());
2109 DeferredInlineSmiOperation* deferred = 2109 DeferredInlineSmiOperation* deferred =
2110 new DeferredInlineSmiOperation(op, 2110 new DeferredInlineSmiOperation(op,
2111 answer.reg(), 2111 answer.reg(),
2112 operand->reg(), 2112 operand->reg(),
2113 operand->number_info(), 2113 operand->type_info(),
2114 smi_value, 2114 smi_value,
2115 overwrite_mode); 2115 overwrite_mode);
2116 if (!operand->number_info().IsSmi()) { 2116 if (!operand->type_info().IsSmi()) {
2117 __ test(operand->reg(), Immediate(kSmiTagMask)); 2117 __ test(operand->reg(), Immediate(kSmiTagMask));
2118 deferred->Branch(not_zero); 2118 deferred->Branch(not_zero);
2119 } else { 2119 } else {
2120 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2120 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg());
2121 } 2121 }
2122 __ mov(answer.reg(), operand->reg()); 2122 __ mov(answer.reg(), operand->reg());
2123 __ SmiUntag(answer.reg()); 2123 __ SmiUntag(answer.reg());
2124 __ shr(answer.reg(), shift_value); 2124 __ shr(answer.reg(), shift_value);
2125 // A negative Smi shifted right two is in the positive Smi range. 2125 // A negative Smi shifted right two is in the positive Smi range.
2126 if (shift_value < 2) { 2126 if (shift_value < 2) {
(...skipping 26 matching lines...) Expand all
2153 right = *operand; 2153 right = *operand;
2154 } 2154 }
2155 operand->Unuse(); 2155 operand->Unuse();
2156 2156
2157 answer = allocator()->Allocate(); 2157 answer = allocator()->Allocate();
2158 DeferredInlineSmiOperationReversed* deferred = 2158 DeferredInlineSmiOperationReversed* deferred =
2159 new DeferredInlineSmiOperationReversed(op, 2159 new DeferredInlineSmiOperationReversed(op,
2160 answer.reg(), 2160 answer.reg(),
2161 smi_value, 2161 smi_value,
2162 right.reg(), 2162 right.reg(),
2163 right.number_info(), 2163 right.type_info(),
2164 overwrite_mode); 2164 overwrite_mode);
2165 __ mov(answer.reg(), Immediate(int_value)); 2165 __ mov(answer.reg(), Immediate(int_value));
2166 __ sar(ecx, kSmiTagSize); 2166 __ sar(ecx, kSmiTagSize);
2167 if (!right.number_info().IsSmi()) { 2167 if (!right.type_info().IsSmi()) {
2168 deferred->Branch(carry); 2168 deferred->Branch(carry);
2169 } else { 2169 } else {
2170 if (FLAG_debug_code) __ AbortIfNotSmi(right.reg()); 2170 if (FLAG_debug_code) __ AbortIfNotSmi(right.reg());
2171 } 2171 }
2172 __ shl_cl(answer.reg()); 2172 __ shl_cl(answer.reg());
2173 __ cmp(answer.reg(), 0xc0000000); 2173 __ cmp(answer.reg(), 0xc0000000);
2174 deferred->Branch(sign); 2174 deferred->Branch(sign);
2175 __ SmiTag(answer.reg()); 2175 __ SmiTag(answer.reg());
2176 2176
2177 deferred->BindExit(); 2177 deferred->BindExit();
2178 } else { 2178 } else {
2179 // Only the least significant 5 bits of the shift value are used. 2179 // Only the least significant 5 bits of the shift value are used.
2180 // In the slow case, this masking is done inside the runtime call. 2180 // In the slow case, this masking is done inside the runtime call.
2181 int shift_value = int_value & 0x1f; 2181 int shift_value = int_value & 0x1f;
2182 operand->ToRegister(); 2182 operand->ToRegister();
2183 if (shift_value == 0) { 2183 if (shift_value == 0) {
2184 // Spill operand so it can be overwritten in the slow case. 2184 // Spill operand so it can be overwritten in the slow case.
2185 frame_->Spill(operand->reg()); 2185 frame_->Spill(operand->reg());
2186 DeferredInlineSmiOperation* deferred = 2186 DeferredInlineSmiOperation* deferred =
2187 new DeferredInlineSmiOperation(op, 2187 new DeferredInlineSmiOperation(op,
2188 operand->reg(), 2188 operand->reg(),
2189 operand->reg(), 2189 operand->reg(),
2190 operand->number_info(), 2190 operand->type_info(),
2191 smi_value, 2191 smi_value,
2192 overwrite_mode); 2192 overwrite_mode);
2193 __ test(operand->reg(), Immediate(kSmiTagMask)); 2193 __ test(operand->reg(), Immediate(kSmiTagMask));
2194 deferred->Branch(not_zero); 2194 deferred->Branch(not_zero);
2195 deferred->BindExit(); 2195 deferred->BindExit();
2196 answer = *operand; 2196 answer = *operand;
2197 } else { 2197 } else {
2198 // Use a fresh temporary for nonzero shift values. 2198 // Use a fresh temporary for nonzero shift values.
2199 answer = allocator()->Allocate(); 2199 answer = allocator()->Allocate();
2200 ASSERT(answer.is_valid()); 2200 ASSERT(answer.is_valid());
2201 DeferredInlineSmiOperation* deferred = 2201 DeferredInlineSmiOperation* deferred =
2202 new DeferredInlineSmiOperation(op, 2202 new DeferredInlineSmiOperation(op,
2203 answer.reg(), 2203 answer.reg(),
2204 operand->reg(), 2204 operand->reg(),
2205 operand->number_info(), 2205 operand->type_info(),
2206 smi_value, 2206 smi_value,
2207 overwrite_mode); 2207 overwrite_mode);
2208 if (!operand->number_info().IsSmi()) { 2208 if (!operand->type_info().IsSmi()) {
2209 __ test(operand->reg(), Immediate(kSmiTagMask)); 2209 __ test(operand->reg(), Immediate(kSmiTagMask));
2210 deferred->Branch(not_zero); 2210 deferred->Branch(not_zero);
2211 } else { 2211 } else {
2212 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2212 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg());
2213 } 2213 }
2214 __ mov(answer.reg(), operand->reg()); 2214 __ mov(answer.reg(), operand->reg());
2215 ASSERT(kSmiTag == 0); // adjust code if not the case 2215 ASSERT(kSmiTag == 0); // adjust code if not the case
2216 // We do no shifts, only the Smi conversion, if shift_value is 1. 2216 // We do no shifts, only the Smi conversion, if shift_value is 1.
2217 if (shift_value > 1) { 2217 if (shift_value > 1) {
2218 __ shl(answer.reg(), shift_value - 1); 2218 __ shl(answer.reg(), shift_value - 1);
(...skipping 13 matching lines...) Expand all
2232 case Token::BIT_AND: { 2232 case Token::BIT_AND: {
2233 operand->ToRegister(); 2233 operand->ToRegister();
2234 frame_->Spill(operand->reg()); 2234 frame_->Spill(operand->reg());
2235 DeferredCode* deferred = NULL; 2235 DeferredCode* deferred = NULL;
2236 if (reversed) { 2236 if (reversed) {
2237 deferred = 2237 deferred =
2238 new DeferredInlineSmiOperationReversed(op, 2238 new DeferredInlineSmiOperationReversed(op,
2239 operand->reg(), 2239 operand->reg(),
2240 smi_value, 2240 smi_value,
2241 operand->reg(), 2241 operand->reg(),
2242 operand->number_info(), 2242 operand->type_info(),
2243 overwrite_mode); 2243 overwrite_mode);
2244 } else { 2244 } else {
2245 deferred = new DeferredInlineSmiOperation(op, 2245 deferred = new DeferredInlineSmiOperation(op,
2246 operand->reg(), 2246 operand->reg(),
2247 operand->reg(), 2247 operand->reg(),
2248 operand->number_info(), 2248 operand->type_info(),
2249 smi_value, 2249 smi_value,
2250 overwrite_mode); 2250 overwrite_mode);
2251 } 2251 }
2252 if (!operand->number_info().IsSmi()) { 2252 if (!operand->type_info().IsSmi()) {
2253 __ test(operand->reg(), Immediate(kSmiTagMask)); 2253 __ test(operand->reg(), Immediate(kSmiTagMask));
2254 deferred->Branch(not_zero); 2254 deferred->Branch(not_zero);
2255 } else { 2255 } else {
2256 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2256 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg());
2257 } 2257 }
2258 if (op == Token::BIT_AND) { 2258 if (op == Token::BIT_AND) {
2259 __ and_(Operand(operand->reg()), Immediate(value)); 2259 __ and_(Operand(operand->reg()), Immediate(value));
2260 } else if (op == Token::BIT_XOR) { 2260 } else if (op == Token::BIT_XOR) {
2261 if (int_value != 0) { 2261 if (int_value != 0) {
2262 __ xor_(Operand(operand->reg()), Immediate(value)); 2262 __ xor_(Operand(operand->reg()), Immediate(value));
(...skipping 11 matching lines...) Expand all
2274 2274
2275 case Token::DIV: 2275 case Token::DIV:
2276 if (!reversed && int_value == 2) { 2276 if (!reversed && int_value == 2) {
2277 operand->ToRegister(); 2277 operand->ToRegister();
2278 frame_->Spill(operand->reg()); 2278 frame_->Spill(operand->reg());
2279 2279
2280 DeferredInlineSmiOperation* deferred = 2280 DeferredInlineSmiOperation* deferred =
2281 new DeferredInlineSmiOperation(op, 2281 new DeferredInlineSmiOperation(op,
2282 operand->reg(), 2282 operand->reg(),
2283 operand->reg(), 2283 operand->reg(),
2284 operand->number_info(), 2284 operand->type_info(),
2285 smi_value, 2285 smi_value,
2286 overwrite_mode); 2286 overwrite_mode);
2287 // Check that lowest log2(value) bits of operand are zero, and test 2287 // Check that lowest log2(value) bits of operand are zero, and test
2288 // smi tag at the same time. 2288 // smi tag at the same time.
2289 ASSERT_EQ(0, kSmiTag); 2289 ASSERT_EQ(0, kSmiTag);
2290 ASSERT_EQ(1, kSmiTagSize); 2290 ASSERT_EQ(1, kSmiTagSize);
2291 __ test(operand->reg(), Immediate(3)); 2291 __ test(operand->reg(), Immediate(3));
2292 deferred->Branch(not_zero); // Branch if non-smi or odd smi. 2292 deferred->Branch(not_zero); // Branch if non-smi or odd smi.
2293 __ sar(operand->reg(), 1); 2293 __ sar(operand->reg(), 1);
2294 deferred->BindExit(); 2294 deferred->BindExit();
(...skipping 15 matching lines...) Expand all
2310 case Token::MOD: 2310 case Token::MOD:
2311 if (!reversed && 2311 if (!reversed &&
2312 int_value != 0 && 2312 int_value != 0 &&
2313 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { 2313 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) {
2314 operand->ToRegister(); 2314 operand->ToRegister();
2315 frame_->Spill(operand->reg()); 2315 frame_->Spill(operand->reg());
2316 DeferredCode* deferred = 2316 DeferredCode* deferred =
2317 new DeferredInlineSmiOperation(op, 2317 new DeferredInlineSmiOperation(op,
2318 operand->reg(), 2318 operand->reg(),
2319 operand->reg(), 2319 operand->reg(),
2320 operand->number_info(), 2320 operand->type_info(),
2321 smi_value, 2321 smi_value,
2322 overwrite_mode); 2322 overwrite_mode);
2323 // Check for negative or non-Smi left hand side. 2323 // Check for negative or non-Smi left hand side.
2324 __ test(operand->reg(), Immediate(kSmiTagMask | 0x80000000)); 2324 __ test(operand->reg(), Immediate(kSmiTagMask | 0x80000000));
2325 deferred->Branch(not_zero); 2325 deferred->Branch(not_zero);
2326 if (int_value < 0) int_value = -int_value; 2326 if (int_value < 0) int_value = -int_value;
2327 if (int_value == 1) { 2327 if (int_value == 1) {
2328 __ mov(operand->reg(), Immediate(Smi::FromInt(0))); 2328 __ mov(operand->reg(), Immediate(Smi::FromInt(0)));
2329 } else { 2329 } else {
2330 __ and_(operand->reg(), (int_value << kSmiTagSize) - 1); 2330 __ and_(operand->reg(), (int_value << kSmiTagSize) - 1);
(...skipping 15 matching lines...) Expand all
2346 } 2346 }
2347 break; 2347 break;
2348 } 2348 }
2349 } 2349 }
2350 ASSERT(answer.is_valid()); 2350 ASSERT(answer.is_valid());
2351 return answer; 2351 return answer;
2352 } 2352 }
2353 2353
2354 2354
2355 static bool CouldBeNaN(const Result& result) { 2355 static bool CouldBeNaN(const Result& result) {
2356 if (result.number_info().IsSmi()) return false; 2356 if (result.type_info().IsSmi()) return false;
2357 if (result.number_info().IsInteger32()) return false; 2357 if (result.type_info().IsInteger32()) return false;
2358 if (!result.is_constant()) return true; 2358 if (!result.is_constant()) return true;
2359 if (!result.handle()->IsHeapNumber()) return false; 2359 if (!result.handle()->IsHeapNumber()) return false;
2360 return isnan(HeapNumber::cast(*result.handle())->value()); 2360 return isnan(HeapNumber::cast(*result.handle())->value());
2361 } 2361 }
2362 2362
2363 2363
2364 void CodeGenerator::Comparison(AstNode* node, 2364 void CodeGenerator::Comparison(AstNode* node,
2365 Condition cc, 2365 Condition cc,
2366 bool strict, 2366 bool strict,
2367 ControlDestination* dest) { 2367 ControlDestination* dest) {
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after
3645 3645
3646 // The break target may be already bound (by the condition), or there 3646 // The break target may be already bound (by the condition), or there
3647 // may not be a valid frame. Bind it only if needed. 3647 // may not be a valid frame. Bind it only if needed.
3648 if (node->break_target()->is_linked()) { 3648 if (node->break_target()->is_linked()) {
3649 node->break_target()->Bind(); 3649 node->break_target()->Bind();
3650 } 3650 }
3651 DecrementLoopNesting(); 3651 DecrementLoopNesting();
3652 } 3652 }
3653 3653
3654 3654
3655 void CodeGenerator::SetTypeForStackSlot(Slot* slot, NumberInfo info) { 3655 void CodeGenerator::SetTypeForStackSlot(Slot* slot, TypeInfo info) {
3656 ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER); 3656 ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER);
3657 if (slot->type() == Slot::LOCAL) { 3657 if (slot->type() == Slot::LOCAL) {
3658 frame_->SetTypeForLocalAt(slot->index(), info); 3658 frame_->SetTypeForLocalAt(slot->index(), info);
3659 } else { 3659 } else {
3660 frame_->SetTypeForParamAt(slot->index(), info); 3660 frame_->SetTypeForParamAt(slot->index(), info);
3661 } 3661 }
3662 if (FLAG_debug_code && info.IsSmi()) { 3662 if (FLAG_debug_code && info.IsSmi()) {
3663 if (slot->type() == Slot::LOCAL) { 3663 if (slot->type() == Slot::LOCAL) {
3664 frame_->PushLocalAt(slot->index()); 3664 frame_->PushLocalAt(slot->index());
3665 } else { 3665 } else {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3765 3765
3766 CheckStack(); // TODO(1222600): ignore if body contains calls. 3766 CheckStack(); // TODO(1222600): ignore if body contains calls.
3767 3767
3768 // We know that the loop index is a smi if it is not modified in the 3768 // We know that the loop index is a smi if it is not modified in the
3769 // loop body and it is checked against a constant limit in the loop 3769 // loop body and it is checked against a constant limit in the loop
3770 // condition. In this case, we reset the static type information of the 3770 // condition. In this case, we reset the static type information of the
3771 // loop index to smi before compiling the body, the update expression, and 3771 // loop index to smi before compiling the body, the update expression, and
3772 // the bottom check of the loop condition. 3772 // the bottom check of the loop condition.
3773 if (node->is_fast_smi_loop()) { 3773 if (node->is_fast_smi_loop()) {
3774 // Set number type of the loop variable to smi. 3774 // Set number type of the loop variable to smi.
3775 SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi()); 3775 SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
3776 } 3776 }
3777 3777
3778 Visit(node->body()); 3778 Visit(node->body());
3779 3779
3780 // If there is an update expression, compile it if necessary. 3780 // If there is an update expression, compile it if necessary.
3781 if (node->next() != NULL) { 3781 if (node->next() != NULL) {
3782 if (node->continue_target()->is_linked()) { 3782 if (node->continue_target()->is_linked()) {
3783 node->continue_target()->Bind(); 3783 node->continue_target()->Bind();
3784 } 3784 }
3785 3785
3786 // Control can reach the update by falling out of the body or by a 3786 // Control can reach the update by falling out of the body or by a
3787 // continue. 3787 // continue.
3788 if (has_valid_frame()) { 3788 if (has_valid_frame()) {
3789 // Record the source position of the statement as this code which 3789 // Record the source position of the statement as this code which
3790 // is after the code for the body actually belongs to the loop 3790 // is after the code for the body actually belongs to the loop
3791 // statement and not the body. 3791 // statement and not the body.
3792 CodeForStatementPosition(node); 3792 CodeForStatementPosition(node);
3793 Visit(node->next()); 3793 Visit(node->next());
3794 } 3794 }
3795 } 3795 }
3796 3796
3797 // Set the type of the loop variable to smi before compiling the test 3797 // Set the type of the loop variable to smi before compiling the test
3798 // expression if we are in a fast smi loop condition. 3798 // expression if we are in a fast smi loop condition.
3799 if (node->is_fast_smi_loop() && has_valid_frame()) { 3799 if (node->is_fast_smi_loop() && has_valid_frame()) {
3800 // Set number type of the loop variable to smi. 3800 // Set number type of the loop variable to smi.
3801 SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi()); 3801 SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
3802 } 3802 }
3803 3803
3804 // Based on the condition analysis, compile the backward jump as 3804 // Based on the condition analysis, compile the backward jump as
3805 // necessary. 3805 // necessary.
3806 switch (info) { 3806 switch (info) {
3807 case ALWAYS_TRUE: 3807 case ALWAYS_TRUE:
3808 if (has_valid_frame()) { 3808 if (has_valid_frame()) {
3809 if (node->next() == NULL) { 3809 if (node->next() == NULL) {
3810 node->continue_target()->Jump(); 3810 node->continue_target()->Jump();
3811 } else { 3811 } else {
(...skipping 2882 matching lines...) Expand 10 before | Expand all | Expand 10 after
6694 } else { 6694 } else {
6695 Load(node->expression()); 6695 Load(node->expression());
6696 bool overwrite = 6696 bool overwrite =
6697 (node->expression()->AsBinaryOperation() != NULL && 6697 (node->expression()->AsBinaryOperation() != NULL &&
6698 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); 6698 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
6699 switch (op) { 6699 switch (op) {
6700 case Token::SUB: { 6700 case Token::SUB: {
6701 GenericUnaryOpStub stub(Token::SUB, overwrite); 6701 GenericUnaryOpStub stub(Token::SUB, overwrite);
6702 Result operand = frame_->Pop(); 6702 Result operand = frame_->Pop();
6703 Result answer = frame_->CallStub(&stub, &operand); 6703 Result answer = frame_->CallStub(&stub, &operand);
6704 answer.set_number_info(NumberInfo::Number()); 6704 answer.set_type_info(TypeInfo::Number());
6705 frame_->Push(&answer); 6705 frame_->Push(&answer);
6706 break; 6706 break;
6707 } 6707 }
6708 case Token::BIT_NOT: { 6708 case Token::BIT_NOT: {
6709 // Smi check. 6709 // Smi check.
6710 JumpTarget smi_label; 6710 JumpTarget smi_label;
6711 JumpTarget continue_label; 6711 JumpTarget continue_label;
6712 Result operand = frame_->Pop(); 6712 Result operand = frame_->Pop();
6713 NumberInfo operand_info = operand.number_info(); 6713 TypeInfo operand_info = operand.type_info();
6714 operand.ToRegister(); 6714 operand.ToRegister();
6715 if (operand_info.IsSmi()) { 6715 if (operand_info.IsSmi()) {
6716 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg()); 6716 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg());
6717 frame_->Spill(operand.reg()); 6717 frame_->Spill(operand.reg());
6718 // Set smi tag bit. It will be reset by the not operation. 6718 // Set smi tag bit. It will be reset by the not operation.
6719 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); 6719 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask));
6720 __ not_(operand.reg()); 6720 __ not_(operand.reg());
6721 Result answer = operand; 6721 Result answer = operand;
6722 answer.set_number_info(NumberInfo::Smi()); 6722 answer.set_type_info(TypeInfo::Smi());
6723 frame_->Push(&answer); 6723 frame_->Push(&answer);
6724 } else { 6724 } else {
6725 __ test(operand.reg(), Immediate(kSmiTagMask)); 6725 __ test(operand.reg(), Immediate(kSmiTagMask));
6726 smi_label.Branch(zero, &operand, taken); 6726 smi_label.Branch(zero, &operand, taken);
6727 6727
6728 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); 6728 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
6729 Result answer = frame_->CallStub(&stub, &operand); 6729 Result answer = frame_->CallStub(&stub, &operand);
6730 continue_label.Jump(&answer); 6730 continue_label.Jump(&answer);
6731 6731
6732 smi_label.Bind(&answer); 6732 smi_label.Bind(&answer);
6733 answer.ToRegister(); 6733 answer.ToRegister();
6734 frame_->Spill(answer.reg()); 6734 frame_->Spill(answer.reg());
6735 // Set smi tag bit. It will be reset by the not operation. 6735 // Set smi tag bit. It will be reset by the not operation.
6736 __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask)); 6736 __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask));
6737 __ not_(answer.reg()); 6737 __ not_(answer.reg());
6738 6738
6739 continue_label.Bind(&answer); 6739 continue_label.Bind(&answer);
6740 if (operand_info.IsInteger32()) { 6740 if (operand_info.IsInteger32()) {
6741 answer.set_number_info(NumberInfo::Integer32()); 6741 answer.set_type_info(TypeInfo::Integer32());
6742 } else { 6742 } else {
6743 answer.set_number_info(NumberInfo::Number()); 6743 answer.set_type_info(TypeInfo::Number());
6744 } 6744 }
6745 frame_->Push(&answer); 6745 frame_->Push(&answer);
6746 } 6746 }
6747 break; 6747 break;
6748 } 6748 }
6749 case Token::ADD: { 6749 case Token::ADD: {
6750 // Smi check. 6750 // Smi check.
6751 JumpTarget continue_label; 6751 JumpTarget continue_label;
6752 Result operand = frame_->Pop(); 6752 Result operand = frame_->Pop();
6753 NumberInfo operand_info = operand.number_info(); 6753 TypeInfo operand_info = operand.type_info();
6754 operand.ToRegister(); 6754 operand.ToRegister();
6755 __ test(operand.reg(), Immediate(kSmiTagMask)); 6755 __ test(operand.reg(), Immediate(kSmiTagMask));
6756 continue_label.Branch(zero, &operand, taken); 6756 continue_label.Branch(zero, &operand, taken);
6757 6757
6758 frame_->Push(&operand); 6758 frame_->Push(&operand);
6759 Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER, 6759 Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER,
6760 CALL_FUNCTION, 1); 6760 CALL_FUNCTION, 1);
6761 6761
6762 continue_label.Bind(&answer); 6762 continue_label.Bind(&answer);
6763 if (operand_info.IsSmi()) { 6763 if (operand_info.IsSmi()) {
6764 answer.set_number_info(NumberInfo::Smi()); 6764 answer.set_type_info(TypeInfo::Smi());
6765 } else if (operand_info.IsInteger32()) { 6765 } else if (operand_info.IsInteger32()) {
6766 answer.set_number_info(NumberInfo::Integer32()); 6766 answer.set_type_info(TypeInfo::Integer32());
6767 } else { 6767 } else {
6768 answer.set_number_info(NumberInfo::Number()); 6768 answer.set_type_info(TypeInfo::Number());
6769 } 6769 }
6770 frame_->Push(&answer); 6770 frame_->Push(&answer);
6771 break; 6771 break;
6772 } 6772 }
6773 default: 6773 default:
6774 // NOT, DELETE, TYPEOF, and VOID are handled outside the 6774 // NOT, DELETE, TYPEOF, and VOID are handled outside the
6775 // switch. 6775 // switch.
6776 UNREACHABLE(); 6776 UNREACHABLE();
6777 } 6777 }
6778 } 6778 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
6898 6898
6899 Result old_value; // Only allocated in the postfix case. 6899 Result old_value; // Only allocated in the postfix case.
6900 if (is_postfix) { 6900 if (is_postfix) {
6901 // Allocate a temporary to preserve the old value. 6901 // Allocate a temporary to preserve the old value.
6902 old_value = allocator_->Allocate(); 6902 old_value = allocator_->Allocate();
6903 ASSERT(old_value.is_valid()); 6903 ASSERT(old_value.is_valid());
6904 __ mov(old_value.reg(), new_value.reg()); 6904 __ mov(old_value.reg(), new_value.reg());
6905 6905
6906 // The return value for postfix operations is the 6906 // The return value for postfix operations is the
6907 // same as the input, and has the same number info. 6907 // same as the input, and has the same number info.
6908 old_value.set_number_info(new_value.number_info()); 6908 old_value.set_type_info(new_value.type_info());
6909 } 6909 }
6910 6910
6911 // Ensure the new value is writable. 6911 // Ensure the new value is writable.
6912 frame_->Spill(new_value.reg()); 6912 frame_->Spill(new_value.reg());
6913 6913
6914 Result tmp; 6914 Result tmp;
6915 if (new_value.is_smi()) { 6915 if (new_value.is_smi()) {
6916 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); 6916 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg());
6917 } else { 6917 } else {
6918 // We don't know statically if the input is a smi. 6918 // We don't know statically if the input is a smi.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
6965 deferred->Branch(overflow); 6965 deferred->Branch(overflow);
6966 __ test(new_value.reg(), Immediate(kSmiTagMask)); 6966 __ test(new_value.reg(), Immediate(kSmiTagMask));
6967 deferred->Branch(not_zero); 6967 deferred->Branch(not_zero);
6968 } 6968 }
6969 } 6969 }
6970 deferred->BindExit(); 6970 deferred->BindExit();
6971 6971
6972 // The result of ++ or -- is an Integer32 if the 6972 // The result of ++ or -- is an Integer32 if the
6973 // input is a smi. Otherwise it is a number. 6973 // input is a smi. Otherwise it is a number.
6974 if (new_value.is_smi()) { 6974 if (new_value.is_smi()) {
6975 new_value.set_number_info(NumberInfo::Integer32()); 6975 new_value.set_type_info(TypeInfo::Integer32());
6976 } else { 6976 } else {
6977 new_value.set_number_info(NumberInfo::Number()); 6977 new_value.set_type_info(TypeInfo::Number());
6978 } 6978 }
6979 6979
6980 // Postfix: store the old value in the allocated slot under the 6980 // Postfix: store the old value in the allocated slot under the
6981 // reference. 6981 // reference.
6982 if (is_postfix) frame_->SetElementAt(target.size(), &old_value); 6982 if (is_postfix) frame_->SetElementAt(target.size(), &old_value);
6983 6983
6984 frame_->Push(&new_value); 6984 frame_->Push(&new_value);
6985 // Non-constant: update the reference. 6985 // Non-constant: update the reference.
6986 if (!is_const) target.SetValue(NOT_CONST_INIT); 6986 if (!is_const) target.SetValue(NOT_CONST_INIT);
6987 } 6987 }
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
7181 if (op == Token::MOD) { 7181 if (op == Token::MOD) {
7182 // Negative zero can arise as a negative divident with a zero result. 7182 // Negative zero can arise as a negative divident with a zero result.
7183 if (!node->no_negative_zero()) { 7183 if (!node->no_negative_zero()) {
7184 Label not_negative_zero; 7184 Label not_negative_zero;
7185 __ test(edx, Operand(edx)); 7185 __ test(edx, Operand(edx));
7186 __ j(not_zero, &not_negative_zero); 7186 __ j(not_zero, &not_negative_zero);
7187 __ test(eax, Operand(eax)); 7187 __ test(eax, Operand(eax));
7188 unsafe_bailout_->Branch(negative); 7188 unsafe_bailout_->Branch(negative);
7189 __ bind(&not_negative_zero); 7189 __ bind(&not_negative_zero);
7190 } 7190 }
7191 Result edx_result(edx, NumberInfo::Integer32()); 7191 Result edx_result(edx, TypeInfo::Integer32());
7192 edx_result.set_untagged_int32(true); 7192 edx_result.set_untagged_int32(true);
7193 frame_->Push(&edx_result); 7193 frame_->Push(&edx_result);
7194 } else { 7194 } else {
7195 ASSERT(op == Token::DIV); 7195 ASSERT(op == Token::DIV);
7196 __ test(edx, Operand(edx)); 7196 __ test(edx, Operand(edx));
7197 unsafe_bailout_->Branch(not_equal); 7197 unsafe_bailout_->Branch(not_equal);
7198 Result eax_result(eax, NumberInfo::Integer32()); 7198 Result eax_result(eax, TypeInfo::Integer32());
7199 eax_result.set_untagged_int32(true); 7199 eax_result.set_untagged_int32(true);
7200 frame_->Push(&eax_result); 7200 frame_->Push(&eax_result);
7201 } 7201 }
7202 break; 7202 break;
7203 } 7203 }
7204 default: 7204 default:
7205 UNREACHABLE(); 7205 UNREACHABLE();
7206 break; 7206 break;
7207 } 7207 }
7208 } 7208 }
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
8075 return result; 8075 return result;
8076 } 8076 }
8077 8077
8078 8078
8079 #undef __ 8079 #undef __
8080 #define __ ACCESS_MASM(masm) 8080 #define __ ACCESS_MASM(masm)
8081 8081
8082 8082
8083 static void CheckTwoForSminess(MacroAssembler* masm, 8083 static void CheckTwoForSminess(MacroAssembler* masm,
8084 Register left, Register right, Register scratch, 8084 Register left, Register right, Register scratch,
8085 NumberInfo left_info, NumberInfo right_info, 8085 TypeInfo left_info, TypeInfo right_info,
8086 DeferredInlineBinaryOperation* deferred) { 8086 DeferredInlineBinaryOperation* deferred) {
8087 if (left.is(right)) { 8087 if (left.is(right)) {
8088 if (!left_info.IsSmi()) { 8088 if (!left_info.IsSmi()) {
8089 __ test(left, Immediate(kSmiTagMask)); 8089 __ test(left, Immediate(kSmiTagMask));
8090 deferred->Branch(not_zero); 8090 deferred->Branch(not_zero);
8091 } else { 8091 } else {
8092 if (FLAG_debug_code) __ AbortIfNotSmi(left); 8092 if (FLAG_debug_code) __ AbortIfNotSmi(left);
8093 } 8093 }
8094 } else if (!left_info.IsSmi()) { 8094 } else if (!left_info.IsSmi()) {
8095 if (!right_info.IsSmi()) { 8095 if (!right_info.IsSmi()) {
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
9576 __ bind(&done); 9576 __ bind(&done);
9577 } 9577 }
9578 9578
9579 9579
9580 // Get the integer part of a heap number. Surprisingly, all this bit twiddling 9580 // Get the integer part of a heap number. Surprisingly, all this bit twiddling
9581 // is faster than using the built-in instructions on floating point registers. 9581 // is faster than using the built-in instructions on floating point registers.
9582 // Trashes edi and ebx. Dest is ecx. Source cannot be ecx or one of the 9582 // Trashes edi and ebx. Dest is ecx. Source cannot be ecx or one of the
9583 // trashed registers. 9583 // trashed registers.
9584 void IntegerConvert(MacroAssembler* masm, 9584 void IntegerConvert(MacroAssembler* masm,
9585 Register source, 9585 Register source,
9586 NumberInfo number_info, 9586 TypeInfo type_info,
9587 bool use_sse3, 9587 bool use_sse3,
9588 Label* conversion_failure) { 9588 Label* conversion_failure) {
9589 ASSERT(!source.is(ecx) && !source.is(edi) && !source.is(ebx)); 9589 ASSERT(!source.is(ecx) && !source.is(edi) && !source.is(ebx));
9590 Label done, right_exponent, normal_exponent; 9590 Label done, right_exponent, normal_exponent;
9591 Register scratch = ebx; 9591 Register scratch = ebx;
9592 Register scratch2 = edi; 9592 Register scratch2 = edi;
9593 if (!number_info.IsInteger32() || !use_sse3) { 9593 if (!type_info.IsInteger32() || !use_sse3) {
9594 // Get exponent word. 9594 // Get exponent word.
9595 __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset)); 9595 __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset));
9596 // Get exponent alone in scratch2. 9596 // Get exponent alone in scratch2.
9597 __ mov(scratch2, scratch); 9597 __ mov(scratch2, scratch);
9598 __ and_(scratch2, HeapNumber::kExponentMask); 9598 __ and_(scratch2, HeapNumber::kExponentMask);
9599 } 9599 }
9600 if (use_sse3) { 9600 if (use_sse3) {
9601 CpuFeatures::Scope scope(SSE3); 9601 CpuFeatures::Scope scope(SSE3);
9602 if (!number_info.IsInteger32()) { 9602 if (!type_info.IsInteger32()) {
9603 // Check whether the exponent is too big for a 64 bit signed integer. 9603 // Check whether the exponent is too big for a 64 bit signed integer.
9604 static const uint32_t kTooBigExponent = 9604 static const uint32_t kTooBigExponent =
9605 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 9605 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
9606 __ cmp(Operand(scratch2), Immediate(kTooBigExponent)); 9606 __ cmp(Operand(scratch2), Immediate(kTooBigExponent));
9607 __ j(greater_equal, conversion_failure); 9607 __ j(greater_equal, conversion_failure);
9608 } 9608 }
9609 // Load x87 register with heap number. 9609 // Load x87 register with heap number.
9610 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); 9610 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset));
9611 // Reserve space for 64 bit answer. 9611 // Reserve space for 64 bit answer.
9612 __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. 9612 __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
9713 __ bind(&negative); 9713 __ bind(&negative);
9714 __ sub(ecx, Operand(scratch2)); 9714 __ sub(ecx, Operand(scratch2));
9715 __ bind(&done); 9715 __ bind(&done);
9716 } 9716 }
9717 } 9717 }
9718 9718
9719 9719
9720 // Input: edx, eax are the left and right objects of a bit op. 9720 // Input: edx, eax are the left and right objects of a bit op.
9721 // Output: eax, ecx are left and right integers for a bit op. 9721 // Output: eax, ecx are left and right integers for a bit op.
9722 void FloatingPointHelper::LoadNumbersAsIntegers(MacroAssembler* masm, 9722 void FloatingPointHelper::LoadNumbersAsIntegers(MacroAssembler* masm,
9723 NumberInfo number_info, 9723 TypeInfo type_info,
9724 bool use_sse3, 9724 bool use_sse3,
9725 Label* conversion_failure) { 9725 Label* conversion_failure) {
9726 // Check float operands. 9726 // Check float operands.
9727 Label arg1_is_object, check_undefined_arg1; 9727 Label arg1_is_object, check_undefined_arg1;
9728 Label arg2_is_object, check_undefined_arg2; 9728 Label arg2_is_object, check_undefined_arg2;
9729 Label load_arg2, done; 9729 Label load_arg2, done;
9730 9730
9731 if (!number_info.IsDouble()) { 9731 if (!type_info.IsDouble()) {
9732 if (!number_info.IsSmi()) { 9732 if (!type_info.IsSmi()) {
9733 __ test(edx, Immediate(kSmiTagMask)); 9733 __ test(edx, Immediate(kSmiTagMask));
9734 __ j(not_zero, &arg1_is_object); 9734 __ j(not_zero, &arg1_is_object);
9735 } else { 9735 } else {
9736 if (FLAG_debug_code) __ AbortIfNotSmi(edx); 9736 if (FLAG_debug_code) __ AbortIfNotSmi(edx);
9737 } 9737 }
9738 __ SmiUntag(edx); 9738 __ SmiUntag(edx);
9739 __ jmp(&load_arg2); 9739 __ jmp(&load_arg2);
9740 } 9740 }
9741 9741
9742 __ bind(&arg1_is_object); 9742 __ bind(&arg1_is_object);
9743 9743
9744 // Get the untagged integer version of the edx heap number in ecx. 9744 // Get the untagged integer version of the edx heap number in ecx.
9745 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); 9745 IntegerConvert(masm, edx, type_info, use_sse3, conversion_failure);
9746 __ mov(edx, ecx); 9746 __ mov(edx, ecx);
9747 9747
9748 // Here edx has the untagged integer, eax has a Smi or a heap number. 9748 // Here edx has the untagged integer, eax has a Smi or a heap number.
9749 __ bind(&load_arg2); 9749 __ bind(&load_arg2);
9750 if (!number_info.IsDouble()) { 9750 if (!type_info.IsDouble()) {
9751 // Test if arg2 is a Smi. 9751 // Test if arg2 is a Smi.
9752 if (!number_info.IsSmi()) { 9752 if (!type_info.IsSmi()) {
9753 __ test(eax, Immediate(kSmiTagMask)); 9753 __ test(eax, Immediate(kSmiTagMask));
9754 __ j(not_zero, &arg2_is_object); 9754 __ j(not_zero, &arg2_is_object);
9755 } else { 9755 } else {
9756 if (FLAG_debug_code) __ AbortIfNotSmi(eax); 9756 if (FLAG_debug_code) __ AbortIfNotSmi(eax);
9757 } 9757 }
9758 __ SmiUntag(eax); 9758 __ SmiUntag(eax);
9759 __ mov(ecx, eax); 9759 __ mov(ecx, eax);
9760 __ jmp(&done); 9760 __ jmp(&done);
9761 } 9761 }
9762 9762
9763 __ bind(&arg2_is_object); 9763 __ bind(&arg2_is_object);
9764 9764
9765 // Get the untagged integer version of the eax heap number in ecx. 9765 // Get the untagged integer version of the eax heap number in ecx.
9766 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); 9766 IntegerConvert(masm, eax, type_info, use_sse3, conversion_failure);
9767 __ bind(&done); 9767 __ bind(&done);
9768 __ mov(eax, edx); 9768 __ mov(eax, edx);
9769 } 9769 }
9770 9770
9771 9771
9772 // Input: edx, eax are the left and right objects of a bit op. 9772 // Input: edx, eax are the left and right objects of a bit op.
9773 // Output: eax, ecx are left and right integers for a bit op. 9773 // Output: eax, ecx are left and right integers for a bit op.
9774 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm, 9774 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm,
9775 bool use_sse3, 9775 bool use_sse3,
9776 Label* conversion_failure) { 9776 Label* conversion_failure) {
(...skipping 17 matching lines...) Expand all
9794 __ jmp(&load_arg2); 9794 __ jmp(&load_arg2);
9795 9795
9796 __ bind(&arg1_is_object); 9796 __ bind(&arg1_is_object);
9797 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 9797 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
9798 __ cmp(ebx, Factory::heap_number_map()); 9798 __ cmp(ebx, Factory::heap_number_map());
9799 __ j(not_equal, &check_undefined_arg1); 9799 __ j(not_equal, &check_undefined_arg1);
9800 9800
9801 // Get the untagged integer version of the edx heap number in ecx. 9801 // Get the untagged integer version of the edx heap number in ecx.
9802 IntegerConvert(masm, 9802 IntegerConvert(masm,
9803 edx, 9803 edx,
9804 NumberInfo::Unknown(), 9804 TypeInfo::Unknown(),
9805 use_sse3, 9805 use_sse3,
9806 conversion_failure); 9806 conversion_failure);
9807 __ mov(edx, ecx); 9807 __ mov(edx, ecx);
9808 9808
9809 // Here edx has the untagged integer, eax has a Smi or a heap number. 9809 // Here edx has the untagged integer, eax has a Smi or a heap number.
9810 __ bind(&load_arg2); 9810 __ bind(&load_arg2);
9811 9811
9812 // Test if arg2 is a Smi. 9812 // Test if arg2 is a Smi.
9813 __ test(eax, Immediate(kSmiTagMask)); 9813 __ test(eax, Immediate(kSmiTagMask));
9814 __ j(not_zero, &arg2_is_object); 9814 __ j(not_zero, &arg2_is_object);
(...skipping 10 matching lines...) Expand all
9825 __ jmp(&done); 9825 __ jmp(&done);
9826 9826
9827 __ bind(&arg2_is_object); 9827 __ bind(&arg2_is_object);
9828 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 9828 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
9829 __ cmp(ebx, Factory::heap_number_map()); 9829 __ cmp(ebx, Factory::heap_number_map());
9830 __ j(not_equal, &check_undefined_arg2); 9830 __ j(not_equal, &check_undefined_arg2);
9831 9831
9832 // Get the untagged integer version of the eax heap number in ecx. 9832 // Get the untagged integer version of the eax heap number in ecx.
9833 IntegerConvert(masm, 9833 IntegerConvert(masm,
9834 eax, 9834 eax,
9835 NumberInfo::Unknown(), 9835 TypeInfo::Unknown(),
9836 use_sse3, 9836 use_sse3,
9837 conversion_failure); 9837 conversion_failure);
9838 __ bind(&done); 9838 __ bind(&done);
9839 __ mov(eax, edx); 9839 __ mov(eax, edx);
9840 } 9840 }
9841 9841
9842 9842
9843 void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm, 9843 void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
9844 NumberInfo number_info, 9844 TypeInfo type_info,
9845 bool use_sse3, 9845 bool use_sse3,
9846 Label* conversion_failure) { 9846 Label* conversion_failure) {
9847 if (number_info.IsNumber()) { 9847 if (type_info.IsNumber()) {
9848 LoadNumbersAsIntegers(masm, number_info, use_sse3, conversion_failure); 9848 LoadNumbersAsIntegers(masm, type_info, use_sse3, conversion_failure);
9849 } else { 9849 } else {
9850 LoadUnknownsAsIntegers(masm, use_sse3, conversion_failure); 9850 LoadUnknownsAsIntegers(masm, use_sse3, conversion_failure);
9851 } 9851 }
9852 } 9852 }
9853 9853
9854 9854
9855 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, 9855 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
9856 Register number) { 9856 Register number) {
9857 Label load_smi, done; 9857 Label load_smi, done;
9858 9858
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
10083 } 10083 }
10084 } else if (op_ == Token::BIT_NOT) { 10084 } else if (op_ == Token::BIT_NOT) {
10085 // Check if the operand is a heap number. 10085 // Check if the operand is a heap number.
10086 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 10086 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
10087 __ cmp(edx, Factory::heap_number_map()); 10087 __ cmp(edx, Factory::heap_number_map());
10088 __ j(not_equal, &slow, not_taken); 10088 __ j(not_equal, &slow, not_taken);
10089 10089
10090 // Convert the heap number in eax to an untagged integer in ecx. 10090 // Convert the heap number in eax to an untagged integer in ecx.
10091 IntegerConvert(masm, 10091 IntegerConvert(masm,
10092 eax, 10092 eax,
10093 NumberInfo::Unknown(), 10093 TypeInfo::Unknown(),
10094 CpuFeatures::IsSupported(SSE3), 10094 CpuFeatures::IsSupported(SSE3),
10095 &slow); 10095 &slow);
10096 10096
10097 // Do the bitwise operation and check if the result fits in a smi. 10097 // Do the bitwise operation and check if the result fits in a smi.
10098 Label try_float; 10098 Label try_float;
10099 __ not_(ecx); 10099 __ not_(ecx);
10100 __ cmp(ecx, 0xc0000000); 10100 __ cmp(ecx, 0xc0000000);
10101 __ j(sign, &try_float, not_taken); 10101 __ j(sign, &try_float, not_taken);
10102 10102
10103 // Tag the result as a smi and we're done. 10103 // Tag the result as a smi and we're done.
(...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after
12329 12329
12330 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 12330 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
12331 // tagged as a small integer. 12331 // tagged as a small integer.
12332 __ bind(&runtime); 12332 __ bind(&runtime);
12333 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 12333 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
12334 } 12334 }
12335 12335
12336 #undef __ 12336 #undef __
12337 12337
12338 } } // namespace v8::internal 12338 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698