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

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

Issue 10919261: Consistently use named getters for Lithium operands on ia32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ia32/lithium-ia32.h » ('j') | src/ia32/lithium-ia32.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 891 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 } 902 }
903 903
904 904
905 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 905 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
906 // Nothing to do. 906 // Nothing to do.
907 } 907 }
908 908
909 909
910 void LCodeGen::DoModI(LModI* instr) { 910 void LCodeGen::DoModI(LModI* instr) {
911 if (instr->hydrogen()->HasPowerOf2Divisor()) { 911 if (instr->hydrogen()->HasPowerOf2Divisor()) {
912 Register dividend = ToRegister(instr->InputAt(0)); 912 Register dividend = ToRegister(instr->left());
913 913
914 int32_t divisor = 914 int32_t divisor =
915 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 915 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
916 916
917 if (divisor < 0) divisor = -divisor; 917 if (divisor < 0) divisor = -divisor;
918 918
919 Label positive_dividend, done; 919 Label positive_dividend, done;
920 __ test(dividend, Operand(dividend)); 920 __ test(dividend, Operand(dividend));
921 __ j(not_sign, &positive_dividend, Label::kNear); 921 __ j(not_sign, &positive_dividend, Label::kNear);
922 __ neg(dividend); 922 __ neg(dividend);
923 __ and_(dividend, divisor - 1); 923 __ and_(dividend, divisor - 1);
924 __ neg(dividend); 924 __ neg(dividend);
925 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 925 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
926 __ j(not_zero, &done, Label::kNear); 926 __ j(not_zero, &done, Label::kNear);
927 DeoptimizeIf(no_condition, instr->environment()); 927 DeoptimizeIf(no_condition, instr->environment());
928 } else { 928 } else {
929 __ jmp(&done, Label::kNear); 929 __ jmp(&done, Label::kNear);
930 } 930 }
931 __ bind(&positive_dividend); 931 __ bind(&positive_dividend);
932 __ and_(dividend, divisor - 1); 932 __ and_(dividend, divisor - 1);
933 __ bind(&done); 933 __ bind(&done);
934 } else { 934 } else {
935 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive; 935 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
936 Register left_reg = ToRegister(instr->InputAt(0)); 936 Register left_reg = ToRegister(instr->left());
937 Register right_reg = ToRegister(instr->InputAt(1)); 937 Register right_reg = ToRegister(instr->right());
938 Register result_reg = ToRegister(instr->result()); 938 Register result_reg = ToRegister(instr->result());
939 939
940 ASSERT(left_reg.is(eax)); 940 ASSERT(left_reg.is(eax));
941 ASSERT(result_reg.is(edx)); 941 ASSERT(result_reg.is(edx));
942 ASSERT(!right_reg.is(eax)); 942 ASSERT(!right_reg.is(eax));
943 ASSERT(!right_reg.is(edx)); 943 ASSERT(!right_reg.is(edx));
944 944
945 // Check for x % 0. 945 // Check for x % 0.
946 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 946 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
947 __ test(right_reg, Operand(right_reg)); 947 __ test(right_reg, Operand(right_reg));
948 DeoptimizeIf(zero, instr->environment()); 948 DeoptimizeIf(zero, instr->environment());
949 } 949 }
950 950
951 __ test(left_reg, Operand(left_reg)); 951 __ test(left_reg, Operand(left_reg));
952 __ j(zero, &remainder_eq_dividend, Label::kNear); 952 __ j(zero, &remainder_eq_dividend, Label::kNear);
953 __ j(sign, &slow, Label::kNear); 953 __ j(sign, &slow, Label::kNear);
954 954
955 __ test(right_reg, Operand(right_reg)); 955 __ test(right_reg, Operand(right_reg));
956 __ j(not_sign, &both_positive, Label::kNear); 956 __ j(not_sign, &both_positive, Label::kNear);
957 // The sign of the divisor doesn't matter. 957 // The sign of the divisor doesn't matter.
958 __ neg(right_reg); 958 __ neg(right_reg);
959 959
960 __ bind(&both_positive); 960 __ bind(&both_positive);
961 // If the dividend is smaller than the nonnegative 961 // If the dividend is smaller than the nonnegative
962 // divisor, the dividend is the result. 962 // divisor, the dividend is the result.
963 __ cmp(left_reg, Operand(right_reg)); 963 __ cmp(left_reg, Operand(right_reg));
964 __ j(less, &remainder_eq_dividend, Label::kNear); 964 __ j(less, &remainder_eq_dividend, Label::kNear);
965 965
966 // Check if the divisor is a PowerOfTwo integer. 966 // Check if the divisor is a PowerOfTwo integer.
967 Register scratch = ToRegister(instr->TempAt(0)); 967 Register scratch = ToRegister(instr->temp());
968 __ mov(scratch, right_reg); 968 __ mov(scratch, right_reg);
969 __ sub(Operand(scratch), Immediate(1)); 969 __ sub(Operand(scratch), Immediate(1));
970 __ test(scratch, Operand(right_reg)); 970 __ test(scratch, Operand(right_reg));
971 __ j(not_zero, &do_subtraction, Label::kNear); 971 __ j(not_zero, &do_subtraction, Label::kNear);
972 __ and_(left_reg, Operand(scratch)); 972 __ and_(left_reg, Operand(scratch));
973 __ jmp(&remainder_eq_dividend, Label::kNear); 973 __ jmp(&remainder_eq_dividend, Label::kNear);
974 974
975 __ bind(&do_subtraction); 975 __ bind(&do_subtraction);
976 const int kUnfolds = 3; 976 const int kUnfolds = 3;
977 // Try a few subtractions of the dividend. 977 // Try a few subtractions of the dividend.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 1013
1014 __ bind(&remainder_eq_dividend); 1014 __ bind(&remainder_eq_dividend);
1015 __ mov(result_reg, left_reg); 1015 __ mov(result_reg, left_reg);
1016 1016
1017 __ bind(&done); 1017 __ bind(&done);
1018 } 1018 }
1019 } 1019 }
1020 1020
1021 1021
1022 void LCodeGen::DoDivI(LDivI* instr) { 1022 void LCodeGen::DoDivI(LDivI* instr) {
1023 LOperand* right = instr->InputAt(1); 1023 LOperand* right = instr->right();
1024 ASSERT(ToRegister(instr->result()).is(eax)); 1024 ASSERT(ToRegister(instr->result()).is(eax));
1025 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 1025 ASSERT(ToRegister(instr->left()).is(eax));
1026 ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); 1026 ASSERT(!ToRegister(instr->right()).is(eax));
1027 ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); 1027 ASSERT(!ToRegister(instr->right()).is(edx));
1028 1028
1029 Register left_reg = eax; 1029 Register left_reg = eax;
1030 1030
1031 // Check for x / 0. 1031 // Check for x / 0.
1032 Register right_reg = ToRegister(right); 1032 Register right_reg = ToRegister(right);
1033 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1033 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1034 __ test(right_reg, ToOperand(right)); 1034 __ test(right_reg, ToOperand(right));
1035 DeoptimizeIf(zero, instr->environment()); 1035 DeoptimizeIf(zero, instr->environment());
1036 } 1036 }
1037 1037
(...skipping 21 matching lines...) Expand all
1059 __ cdq(); 1059 __ cdq();
1060 __ idiv(right_reg); 1060 __ idiv(right_reg);
1061 1061
1062 // Deoptimize if remainder is not 0. 1062 // Deoptimize if remainder is not 0.
1063 __ test(edx, Operand(edx)); 1063 __ test(edx, Operand(edx));
1064 DeoptimizeIf(not_zero, instr->environment()); 1064 DeoptimizeIf(not_zero, instr->environment());
1065 } 1065 }
1066 1066
1067 1067
1068 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 1068 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1069 ASSERT(instr->InputAt(1)->IsConstantOperand()); 1069 ASSERT(instr->right()->IsConstantOperand());
1070 1070
1071 Register dividend = ToRegister(instr->InputAt(0)); 1071 Register dividend = ToRegister(instr->left());
1072 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1))); 1072 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1073 Register result = ToRegister(instr->result()); 1073 Register result = ToRegister(instr->result());
1074 1074
1075 switch (divisor) { 1075 switch (divisor) {
1076 case 0: 1076 case 0:
1077 DeoptimizeIf(no_condition, instr->environment()); 1077 DeoptimizeIf(no_condition, instr->environment());
1078 return; 1078 return;
1079 1079
1080 case 1: 1080 case 1:
1081 __ Move(result, dividend); 1081 __ Move(result, dividend);
1082 return; 1082 return;
(...skipping 25 matching lines...) Expand all
1108 __ shl(dividend, 32 - power); 1108 __ shl(dividend, 32 - power);
1109 __ sar(result, power); 1109 __ sar(result, power);
1110 __ not_(dividend); 1110 __ not_(dividend);
1111 // Clear result.sign if dividend.sign is set. 1111 // Clear result.sign if dividend.sign is set.
1112 __ and_(result, dividend); 1112 __ and_(result, dividend);
1113 } else { 1113 } else {
1114 __ Move(result, dividend); 1114 __ Move(result, dividend);
1115 __ sar(result, power); 1115 __ sar(result, power);
1116 } 1116 }
1117 } else { 1117 } else {
1118 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 1118 ASSERT(ToRegister(instr->left()).is(eax));
1119 ASSERT(ToRegister(instr->result()).is(edx)); 1119 ASSERT(ToRegister(instr->result()).is(edx));
1120 Register scratch = ToRegister(instr->TempAt(0)); 1120 Register scratch = ToRegister(instr->temp());
1121 1121
1122 // Find b which: 2^b < divisor_abs < 2^(b+1). 1122 // Find b which: 2^b < divisor_abs < 2^(b+1).
1123 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 1123 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
1124 unsigned shift = 32 + b; // Precision +1bit (effectively). 1124 unsigned shift = 32 + b; // Precision +1bit (effectively).
1125 double multiplier_f = 1125 double multiplier_f =
1126 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 1126 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
1127 int64_t multiplier; 1127 int64_t multiplier;
1128 if (multiplier_f - floor(multiplier_f) < 0.5) { 1128 if (multiplier_f - floor(multiplier_f) < 0.5) {
1129 multiplier = static_cast<int64_t>(floor(multiplier_f)); 1129 multiplier = static_cast<int64_t>(floor(multiplier_f));
1130 } else { 1130 } else {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 __ cmp(reg_lo, 0xC0000000); 1162 __ cmp(reg_lo, 0xC0000000);
1163 __ setcc(above_equal, reg_byte_scratch); 1163 __ setcc(above_equal, reg_byte_scratch);
1164 __ add(edx, reg_byte_scratch); 1164 __ add(edx, reg_byte_scratch);
1165 } 1165 }
1166 __ sar(edx, shift - 32); 1166 __ sar(edx, shift - 32);
1167 } 1167 }
1168 } 1168 }
1169 1169
1170 1170
1171 void LCodeGen::DoMulI(LMulI* instr) { 1171 void LCodeGen::DoMulI(LMulI* instr) {
1172 Register left = ToRegister(instr->InputAt(0)); 1172 Register left = ToRegister(instr->left());
1173 LOperand* right = instr->InputAt(1); 1173 LOperand* right = instr->right();
1174 1174
1175 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1175 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1176 __ mov(ToRegister(instr->TempAt(0)), left); 1176 __ mov(ToRegister(instr->temp()), left);
1177 } 1177 }
1178 1178
1179 if (right->IsConstantOperand()) { 1179 if (right->IsConstantOperand()) {
1180 // Try strength reductions on the multiplication. 1180 // Try strength reductions on the multiplication.
1181 // All replacement instructions are at most as long as the imul 1181 // All replacement instructions are at most as long as the imul
1182 // and have better latency. 1182 // and have better latency.
1183 int constant = ToInteger32(LConstantOperand::cast(right)); 1183 int constant = ToInteger32(LConstantOperand::cast(right));
1184 if (constant == -1) { 1184 if (constant == -1) {
1185 __ neg(left); 1185 __ neg(left);
1186 } else if (constant == 0) { 1186 } else if (constant == 0) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 // Bail out if the result is supposed to be negative zero. 1232 // Bail out if the result is supposed to be negative zero.
1233 Label done; 1233 Label done;
1234 __ test(left, Operand(left)); 1234 __ test(left, Operand(left));
1235 __ j(not_zero, &done, Label::kNear); 1235 __ j(not_zero, &done, Label::kNear);
1236 if (right->IsConstantOperand()) { 1236 if (right->IsConstantOperand()) {
1237 if (ToInteger32(LConstantOperand::cast(right)) <= 0) { 1237 if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
1238 DeoptimizeIf(no_condition, instr->environment()); 1238 DeoptimizeIf(no_condition, instr->environment());
1239 } 1239 }
1240 } else { 1240 } else {
1241 // Test the non-zero operand for negative sign. 1241 // Test the non-zero operand for negative sign.
1242 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right)); 1242 __ or_(ToRegister(instr->temp()), ToOperand(right));
1243 DeoptimizeIf(sign, instr->environment()); 1243 DeoptimizeIf(sign, instr->environment());
1244 } 1244 }
1245 __ bind(&done); 1245 __ bind(&done);
1246 } 1246 }
1247 } 1247 }
1248 1248
1249 1249
1250 void LCodeGen::DoBitI(LBitI* instr) { 1250 void LCodeGen::DoBitI(LBitI* instr) {
1251 LOperand* left = instr->InputAt(0); 1251 LOperand* left = instr->left();
1252 LOperand* right = instr->InputAt(1); 1252 LOperand* right = instr->right();
1253 ASSERT(left->Equals(instr->result())); 1253 ASSERT(left->Equals(instr->result()));
1254 ASSERT(left->IsRegister()); 1254 ASSERT(left->IsRegister());
1255 1255
1256 if (right->IsConstantOperand()) { 1256 if (right->IsConstantOperand()) {
1257 int right_operand = ToInteger32(LConstantOperand::cast(right)); 1257 int right_operand = ToInteger32(LConstantOperand::cast(right));
1258 switch (instr->op()) { 1258 switch (instr->op()) {
1259 case Token::BIT_AND: 1259 case Token::BIT_AND:
1260 __ and_(ToRegister(left), right_operand); 1260 __ and_(ToRegister(left), right_operand);
1261 break; 1261 break;
1262 case Token::BIT_OR: 1262 case Token::BIT_OR:
(...skipping 19 matching lines...) Expand all
1282 break; 1282 break;
1283 default: 1283 default:
1284 UNREACHABLE(); 1284 UNREACHABLE();
1285 break; 1285 break;
1286 } 1286 }
1287 } 1287 }
1288 } 1288 }
1289 1289
1290 1290
1291 void LCodeGen::DoShiftI(LShiftI* instr) { 1291 void LCodeGen::DoShiftI(LShiftI* instr) {
1292 LOperand* left = instr->InputAt(0); 1292 LOperand* left = instr->left();
1293 LOperand* right = instr->InputAt(1); 1293 LOperand* right = instr->right();
1294 ASSERT(left->Equals(instr->result())); 1294 ASSERT(left->Equals(instr->result()));
1295 ASSERT(left->IsRegister()); 1295 ASSERT(left->IsRegister());
1296 if (right->IsRegister()) { 1296 if (right->IsRegister()) {
1297 ASSERT(ToRegister(right).is(ecx)); 1297 ASSERT(ToRegister(right).is(ecx));
1298 1298
1299 switch (instr->op()) { 1299 switch (instr->op()) {
1300 case Token::SAR: 1300 case Token::SAR:
1301 __ sar_cl(ToRegister(left)); 1301 __ sar_cl(ToRegister(left));
1302 break; 1302 break;
1303 case Token::SHR: 1303 case Token::SHR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 break; 1338 break;
1339 default: 1339 default:
1340 UNREACHABLE(); 1340 UNREACHABLE();
1341 break; 1341 break;
1342 } 1342 }
1343 } 1343 }
1344 } 1344 }
1345 1345
1346 1346
1347 void LCodeGen::DoSubI(LSubI* instr) { 1347 void LCodeGen::DoSubI(LSubI* instr) {
1348 LOperand* left = instr->InputAt(0); 1348 LOperand* left = instr->left();
1349 LOperand* right = instr->InputAt(1); 1349 LOperand* right = instr->right();
1350 ASSERT(left->Equals(instr->result())); 1350 ASSERT(left->Equals(instr->result()));
1351 1351
1352 if (right->IsConstantOperand()) { 1352 if (right->IsConstantOperand()) {
1353 __ sub(ToOperand(left), ToInteger32Immediate(right)); 1353 __ sub(ToOperand(left), ToInteger32Immediate(right));
1354 } else { 1354 } else {
1355 __ sub(ToRegister(left), ToOperand(right)); 1355 __ sub(ToRegister(left), ToOperand(right));
1356 } 1356 }
1357 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1357 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1358 DeoptimizeIf(overflow, instr->environment()); 1358 DeoptimizeIf(overflow, instr->environment());
1359 } 1359 }
1360 } 1360 }
1361 1361
1362 1362
1363 void LCodeGen::DoConstantI(LConstantI* instr) { 1363 void LCodeGen::DoConstantI(LConstantI* instr) {
1364 ASSERT(instr->result()->IsRegister()); 1364 ASSERT(instr->result()->IsRegister());
1365 __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1365 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1366 } 1366 }
1367 1367
1368 1368
1369 void LCodeGen::DoConstantD(LConstantD* instr) { 1369 void LCodeGen::DoConstantD(LConstantD* instr) {
1370 ASSERT(instr->result()->IsDoubleRegister()); 1370 ASSERT(instr->result()->IsDoubleRegister());
1371 XMMRegister res = ToDoubleRegister(instr->result()); 1371 XMMRegister res = ToDoubleRegister(instr->result());
1372 double v = instr->value(); 1372 double v = instr->value();
1373 // Use xor to produce +0.0 in a fast and compact way, but avoid to 1373 // Use xor to produce +0.0 in a fast and compact way, but avoid to
1374 // do so if the constant is -0.0. 1374 // do so if the constant is -0.0.
1375 if (BitCast<uint64_t, double>(v) == 0) { 1375 if (BitCast<uint64_t, double>(v) == 0) {
1376 __ xorps(res, res); 1376 __ xorps(res, res);
1377 } else { 1377 } else {
1378 Register temp = ToRegister(instr->TempAt(0)); 1378 Register temp = ToRegister(instr->temp());
1379 uint64_t int_val = BitCast<uint64_t, double>(v); 1379 uint64_t int_val = BitCast<uint64_t, double>(v);
1380 int32_t lower = static_cast<int32_t>(int_val); 1380 int32_t lower = static_cast<int32_t>(int_val);
1381 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 1381 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
1382 if (CpuFeatures::IsSupported(SSE4_1)) { 1382 if (CpuFeatures::IsSupported(SSE4_1)) {
1383 CpuFeatures::Scope scope(SSE4_1); 1383 CpuFeatures::Scope scope(SSE4_1);
1384 if (lower != 0) { 1384 if (lower != 0) {
1385 __ Set(temp, Immediate(lower)); 1385 __ Set(temp, Immediate(lower));
1386 __ movd(res, Operand(temp)); 1386 __ movd(res, Operand(temp));
1387 __ Set(temp, Immediate(upper)); 1387 __ Set(temp, Immediate(upper));
1388 __ pinsrd(res, Operand(temp), 1); 1388 __ pinsrd(res, Operand(temp), 1);
(...skipping 22 matching lines...) Expand all
1411 if (handle->IsHeapObject()) { 1411 if (handle->IsHeapObject()) {
1412 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); 1412 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle));
1413 } else { 1413 } else {
1414 __ Set(reg, Immediate(handle)); 1414 __ Set(reg, Immediate(handle));
1415 } 1415 }
1416 } 1416 }
1417 1417
1418 1418
1419 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1419 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1420 Register result = ToRegister(instr->result()); 1420 Register result = ToRegister(instr->result());
1421 Register array = ToRegister(instr->InputAt(0)); 1421 Register array = ToRegister(instr->value());
1422 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); 1422 __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
1423 } 1423 }
1424 1424
1425 1425
1426 void LCodeGen::DoFixedArrayBaseLength( 1426 void LCodeGen::DoFixedArrayBaseLength(
1427 LFixedArrayBaseLength* instr) { 1427 LFixedArrayBaseLength* instr) {
1428 Register result = ToRegister(instr->result()); 1428 Register result = ToRegister(instr->result());
1429 Register array = ToRegister(instr->InputAt(0)); 1429 Register array = ToRegister(instr->value());
1430 __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset)); 1430 __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
1431 } 1431 }
1432 1432
1433 1433
1434 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1434 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1435 Register result = ToRegister(instr->result()); 1435 Register result = ToRegister(instr->result());
1436 Register map = ToRegister(instr->InputAt(0)); 1436 Register map = ToRegister(instr->value());
1437 __ EnumLength(result, map); 1437 __ EnumLength(result, map);
1438 } 1438 }
1439 1439
1440 1440
1441 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1441 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1442 Register result = ToRegister(instr->result()); 1442 Register result = ToRegister(instr->result());
1443 Register input = ToRegister(instr->InputAt(0)); 1443 Register input = ToRegister(instr->value());
1444 1444
1445 // Load map into |result|. 1445 // Load map into |result|.
1446 __ mov(result, FieldOperand(input, HeapObject::kMapOffset)); 1446 __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
1447 // Load the map's "bit field 2" into |result|. We only need the first byte, 1447 // Load the map's "bit field 2" into |result|. We only need the first byte,
1448 // but the following masking takes care of that anyway. 1448 // but the following masking takes care of that anyway.
1449 __ mov(result, FieldOperand(result, Map::kBitField2Offset)); 1449 __ mov(result, FieldOperand(result, Map::kBitField2Offset));
1450 // Retrieve elements_kind from bit field 2. 1450 // Retrieve elements_kind from bit field 2.
1451 __ and_(result, Map::kElementsKindMask); 1451 __ and_(result, Map::kElementsKindMask);
1452 __ shr(result, Map::kElementsKindShift); 1452 __ shr(result, Map::kElementsKindShift);
1453 } 1453 }
1454 1454
1455 1455
1456 void LCodeGen::DoValueOf(LValueOf* instr) { 1456 void LCodeGen::DoValueOf(LValueOf* instr) {
1457 Register input = ToRegister(instr->InputAt(0)); 1457 Register input = ToRegister(instr->value());
1458 Register result = ToRegister(instr->result()); 1458 Register result = ToRegister(instr->result());
1459 Register map = ToRegister(instr->TempAt(0)); 1459 Register map = ToRegister(instr->temp());
1460 ASSERT(input.is(result)); 1460 ASSERT(input.is(result));
1461 1461
1462 Label done; 1462 Label done;
1463 // If the object is a smi return the object. 1463 // If the object is a smi return the object.
1464 __ JumpIfSmi(input, &done, Label::kNear); 1464 __ JumpIfSmi(input, &done, Label::kNear);
1465 1465
1466 // If the object is not a value type, return the object. 1466 // If the object is not a value type, return the object.
1467 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1467 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1468 __ j(not_equal, &done, Label::kNear); 1468 __ j(not_equal, &done, Label::kNear);
1469 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1469 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1470 1470
1471 __ bind(&done); 1471 __ bind(&done);
1472 } 1472 }
1473 1473
1474 1474
1475 void LCodeGen::DoDateField(LDateField* instr) { 1475 void LCodeGen::DoDateField(LDateField* instr) {
1476 Register object = ToRegister(instr->InputAt(0)); 1476 Register object = ToRegister(instr->date());
1477 Register result = ToRegister(instr->result()); 1477 Register result = ToRegister(instr->result());
1478 Register scratch = ToRegister(instr->TempAt(0)); 1478 Register scratch = ToRegister(instr->temp());
1479 Smi* index = instr->index(); 1479 Smi* index = instr->index();
1480 Label runtime, done; 1480 Label runtime, done;
1481 ASSERT(object.is(result)); 1481 ASSERT(object.is(result));
1482 ASSERT(object.is(eax)); 1482 ASSERT(object.is(eax));
1483 1483
1484 __ test(object, Immediate(kSmiTagMask)); 1484 __ test(object, Immediate(kSmiTagMask));
1485 DeoptimizeIf(zero, instr->environment()); 1485 DeoptimizeIf(zero, instr->environment());
1486 __ CmpObjectType(object, JS_DATE_TYPE, scratch); 1486 __ CmpObjectType(object, JS_DATE_TYPE, scratch);
1487 DeoptimizeIf(not_equal, instr->environment()); 1487 DeoptimizeIf(not_equal, instr->environment());
1488 1488
(...skipping 13 matching lines...) Expand all
1502 __ PrepareCallCFunction(2, scratch); 1502 __ PrepareCallCFunction(2, scratch);
1503 __ mov(Operand(esp, 0), object); 1503 __ mov(Operand(esp, 0), object);
1504 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); 1504 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
1505 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1505 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1506 __ bind(&done); 1506 __ bind(&done);
1507 } 1507 }
1508 } 1508 }
1509 1509
1510 1510
1511 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1511 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1512 LOperand* input = instr->InputAt(0); 1512 LOperand* input = instr->value();
1513 ASSERT(input->Equals(instr->result())); 1513 ASSERT(input->Equals(instr->result()));
1514 __ not_(ToRegister(input)); 1514 __ not_(ToRegister(input));
1515 } 1515 }
1516 1516
1517 1517
1518 void LCodeGen::DoThrow(LThrow* instr) { 1518 void LCodeGen::DoThrow(LThrow* instr) {
1519 __ push(ToOperand(instr->value())); 1519 __ push(ToOperand(instr->value()));
1520 ASSERT(ToRegister(instr->context()).is(esi)); 1520 ASSERT(ToRegister(instr->context()).is(esi));
1521 CallRuntime(Runtime::kThrow, 1, instr); 1521 CallRuntime(Runtime::kThrow, 1, instr);
1522 1522
1523 if (FLAG_debug_code) { 1523 if (FLAG_debug_code) {
1524 Comment("Unreachable code."); 1524 Comment("Unreachable code.");
1525 __ int3(); 1525 __ int3();
1526 } 1526 }
1527 } 1527 }
1528 1528
1529 1529
1530 void LCodeGen::DoAddI(LAddI* instr) { 1530 void LCodeGen::DoAddI(LAddI* instr) {
1531 LOperand* left = instr->InputAt(0); 1531 LOperand* left = instr->left();
1532 LOperand* right = instr->InputAt(1); 1532 LOperand* right = instr->right();
1533 ASSERT(left->Equals(instr->result())); 1533 ASSERT(left->Equals(instr->result()));
1534 1534
1535 if (right->IsConstantOperand()) { 1535 if (right->IsConstantOperand()) {
1536 __ add(ToOperand(left), ToInteger32Immediate(right)); 1536 __ add(ToOperand(left), ToInteger32Immediate(right));
1537 } else { 1537 } else {
1538 __ add(ToRegister(left), ToOperand(right)); 1538 __ add(ToRegister(left), ToOperand(right));
1539 } 1539 }
1540 1540
1541 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1541 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1542 DeoptimizeIf(overflow, instr->environment()); 1542 DeoptimizeIf(overflow, instr->environment());
1543 } 1543 }
1544 } 1544 }
1545 1545
1546 1546
1547 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1547 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1548 LOperand* left = instr->InputAt(0); 1548 LOperand* left = instr->left();
1549 LOperand* right = instr->InputAt(1); 1549 LOperand* right = instr->right();
1550 ASSERT(left->Equals(instr->result())); 1550 ASSERT(left->Equals(instr->result()));
1551 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1551 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1552 if (instr->hydrogen()->representation().IsInteger32()) { 1552 if (instr->hydrogen()->representation().IsInteger32()) {
1553 Label return_left; 1553 Label return_left;
1554 Condition condition = (operation == HMathMinMax::kMathMin) 1554 Condition condition = (operation == HMathMinMax::kMathMin)
1555 ? less_equal 1555 ? less_equal
1556 : greater_equal; 1556 : greater_equal;
1557 if (right->IsConstantOperand()) { 1557 if (right->IsConstantOperand()) {
1558 Operand left_op = ToOperand(left); 1558 Operand left_op = ToOperand(left);
1559 Immediate right_imm = ToInteger32Immediate(right); 1559 Immediate right_imm = ToInteger32Immediate(right);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 __ j(parity_even, &return_left, Label::kNear); // left == NaN. 1599 __ j(parity_even, &return_left, Label::kNear); // left == NaN.
1600 __ bind(&return_right); 1600 __ bind(&return_right);
1601 __ movsd(left_reg, right_reg); 1601 __ movsd(left_reg, right_reg);
1602 1602
1603 __ bind(&return_left); 1603 __ bind(&return_left);
1604 } 1604 }
1605 } 1605 }
1606 1606
1607 1607
1608 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1608 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1609 XMMRegister left = ToDoubleRegister(instr->InputAt(0)); 1609 XMMRegister left = ToDoubleRegister(instr->left());
1610 XMMRegister right = ToDoubleRegister(instr->InputAt(1)); 1610 XMMRegister right = ToDoubleRegister(instr->right());
1611 XMMRegister result = ToDoubleRegister(instr->result()); 1611 XMMRegister result = ToDoubleRegister(instr->result());
1612 // Modulo uses a fixed result register. 1612 // Modulo uses a fixed result register.
1613 ASSERT(instr->op() == Token::MOD || left.is(result)); 1613 ASSERT(instr->op() == Token::MOD || left.is(result));
1614 switch (instr->op()) { 1614 switch (instr->op()) {
1615 case Token::ADD: 1615 case Token::ADD:
1616 __ addsd(left, right); 1616 __ addsd(left, right);
1617 break; 1617 break;
1618 case Token::SUB: 1618 case Token::SUB:
1619 __ subsd(left, right); 1619 __ subsd(left, right);
1620 break; 1620 break;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 } 1686 }
1687 } 1687 }
1688 1688
1689 1689
1690 void LCodeGen::DoBranch(LBranch* instr) { 1690 void LCodeGen::DoBranch(LBranch* instr) {
1691 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1691 int true_block = chunk_->LookupDestination(instr->true_block_id());
1692 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1692 int false_block = chunk_->LookupDestination(instr->false_block_id());
1693 1693
1694 Representation r = instr->hydrogen()->value()->representation(); 1694 Representation r = instr->hydrogen()->value()->representation();
1695 if (r.IsInteger32()) { 1695 if (r.IsInteger32()) {
1696 Register reg = ToRegister(instr->InputAt(0)); 1696 Register reg = ToRegister(instr->value());
1697 __ test(reg, Operand(reg)); 1697 __ test(reg, Operand(reg));
1698 EmitBranch(true_block, false_block, not_zero); 1698 EmitBranch(true_block, false_block, not_zero);
1699 } else if (r.IsDouble()) { 1699 } else if (r.IsDouble()) {
1700 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); 1700 XMMRegister reg = ToDoubleRegister(instr->value());
1701 __ xorps(xmm0, xmm0); 1701 __ xorps(xmm0, xmm0);
1702 __ ucomisd(reg, xmm0); 1702 __ ucomisd(reg, xmm0);
1703 EmitBranch(true_block, false_block, not_equal); 1703 EmitBranch(true_block, false_block, not_equal);
1704 } else { 1704 } else {
1705 ASSERT(r.IsTagged()); 1705 ASSERT(r.IsTagged());
1706 Register reg = ToRegister(instr->InputAt(0)); 1706 Register reg = ToRegister(instr->value());
1707 HType type = instr->hydrogen()->value()->type(); 1707 HType type = instr->hydrogen()->value()->type();
1708 if (type.IsBoolean()) { 1708 if (type.IsBoolean()) {
1709 __ cmp(reg, factory()->true_value()); 1709 __ cmp(reg, factory()->true_value());
1710 EmitBranch(true_block, false_block, equal); 1710 EmitBranch(true_block, false_block, equal);
1711 } else if (type.IsSmi()) { 1711 } else if (type.IsSmi()) {
1712 __ test(reg, Operand(reg)); 1712 __ test(reg, Operand(reg));
1713 EmitBranch(true_block, false_block, not_equal); 1713 EmitBranch(true_block, false_block, not_equal);
1714 } else { 1714 } else {
1715 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1715 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1716 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1716 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 27 matching lines...) Expand all
1744 __ j(equal, false_label); 1744 __ j(equal, false_label);
1745 __ JumpIfSmi(reg, true_label); 1745 __ JumpIfSmi(reg, true_label);
1746 } else if (expected.NeedsMap()) { 1746 } else if (expected.NeedsMap()) {
1747 // If we need a map later and have a Smi -> deopt. 1747 // If we need a map later and have a Smi -> deopt.
1748 __ test(reg, Immediate(kSmiTagMask)); 1748 __ test(reg, Immediate(kSmiTagMask));
1749 DeoptimizeIf(zero, instr->environment()); 1749 DeoptimizeIf(zero, instr->environment());
1750 } 1750 }
1751 1751
1752 Register map = no_reg; // Keep the compiler happy. 1752 Register map = no_reg; // Keep the compiler happy.
1753 if (expected.NeedsMap()) { 1753 if (expected.NeedsMap()) {
1754 map = ToRegister(instr->TempAt(0)); 1754 map = ToRegister(instr->temp());
1755 ASSERT(!map.is(reg)); 1755 ASSERT(!map.is(reg));
1756 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 1756 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
1757 1757
1758 if (expected.CanBeUndetectable()) { 1758 if (expected.CanBeUndetectable()) {
1759 // Undetectable -> false. 1759 // Undetectable -> false.
1760 __ test_b(FieldOperand(map, Map::kBitFieldOffset), 1760 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
1761 1 << Map::kIsUndetectable); 1761 1 << Map::kIsUndetectable);
1762 __ j(not_zero, false_label); 1762 __ j(not_zero, false_label);
1763 } 1763 }
1764 } 1764 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 case Token::IN: 1837 case Token::IN:
1838 case Token::INSTANCEOF: 1838 case Token::INSTANCEOF:
1839 default: 1839 default:
1840 UNREACHABLE(); 1840 UNREACHABLE();
1841 } 1841 }
1842 return cond; 1842 return cond;
1843 } 1843 }
1844 1844
1845 1845
1846 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1846 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1847 LOperand* left = instr->InputAt(0); 1847 LOperand* left = instr->left();
1848 LOperand* right = instr->InputAt(1); 1848 LOperand* right = instr->right();
1849 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1849 int false_block = chunk_->LookupDestination(instr->false_block_id());
1850 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1850 int true_block = chunk_->LookupDestination(instr->true_block_id());
1851 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1851 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1852 1852
1853 if (left->IsConstantOperand() && right->IsConstantOperand()) { 1853 if (left->IsConstantOperand() && right->IsConstantOperand()) {
1854 // We can statically evaluate the comparison. 1854 // We can statically evaluate the comparison.
1855 double left_val = ToDouble(LConstantOperand::cast(left)); 1855 double left_val = ToDouble(LConstantOperand::cast(left));
1856 double right_val = ToDouble(LConstantOperand::cast(right)); 1856 double right_val = ToDouble(LConstantOperand::cast(right));
1857 int next_block = 1857 int next_block =
1858 EvalComparison(instr->op(), left_val, right_val) ? true_block 1858 EvalComparison(instr->op(), left_val, right_val) ? true_block
(...skipping 15 matching lines...) Expand all
1874 } else { 1874 } else {
1875 __ cmp(ToRegister(left), ToOperand(right)); 1875 __ cmp(ToRegister(left), ToOperand(right));
1876 } 1876 }
1877 } 1877 }
1878 EmitBranch(true_block, false_block, cc); 1878 EmitBranch(true_block, false_block, cc);
1879 } 1879 }
1880 } 1880 }
1881 1881
1882 1882
1883 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1883 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1884 Register left = ToRegister(instr->InputAt(0)); 1884 Register left = ToRegister(instr->left());
1885 Operand right = ToOperand(instr->InputAt(1)); 1885 Operand right = ToOperand(instr->right());
1886 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1886 int false_block = chunk_->LookupDestination(instr->false_block_id());
1887 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1887 int true_block = chunk_->LookupDestination(instr->true_block_id());
1888 1888
1889 __ cmp(left, Operand(right)); 1889 __ cmp(left, Operand(right));
1890 EmitBranch(true_block, false_block, equal); 1890 EmitBranch(true_block, false_block, equal);
1891 } 1891 }
1892 1892
1893 1893
1894 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1894 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1895 Register left = ToRegister(instr->InputAt(0)); 1895 Register left = ToRegister(instr->left());
1896 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1896 int true_block = chunk_->LookupDestination(instr->true_block_id());
1897 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1897 int false_block = chunk_->LookupDestination(instr->false_block_id());
1898 1898
1899 __ cmp(left, instr->hydrogen()->right()); 1899 __ cmp(left, instr->hydrogen()->right());
1900 EmitBranch(true_block, false_block, equal); 1900 EmitBranch(true_block, false_block, equal);
1901 } 1901 }
1902 1902
1903 1903
1904 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 1904 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
1905 Register reg = ToRegister(instr->InputAt(0)); 1905 Register reg = ToRegister(instr->value());
1906 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1906 int false_block = chunk_->LookupDestination(instr->false_block_id());
1907 1907
1908 // If the expression is known to be untagged or a smi, then it's definitely 1908 // If the expression is known to be untagged or a smi, then it's definitely
1909 // not null, and it can't be a an undetectable object. 1909 // not null, and it can't be a an undetectable object.
1910 if (instr->hydrogen()->representation().IsSpecialization() || 1910 if (instr->hydrogen()->representation().IsSpecialization() ||
1911 instr->hydrogen()->type().IsSmi()) { 1911 instr->hydrogen()->type().IsSmi()) {
1912 EmitGoto(false_block); 1912 EmitGoto(false_block);
1913 return; 1913 return;
1914 } 1914 }
1915 1915
1916 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1916 int true_block = chunk_->LookupDestination(instr->true_block_id());
1917 Handle<Object> nil_value = instr->nil() == kNullValue ? 1917 Handle<Object> nil_value = instr->nil() == kNullValue ?
1918 factory()->null_value() : 1918 factory()->null_value() :
1919 factory()->undefined_value(); 1919 factory()->undefined_value();
1920 __ cmp(reg, nil_value); 1920 __ cmp(reg, nil_value);
1921 if (instr->kind() == kStrictEquality) { 1921 if (instr->kind() == kStrictEquality) {
1922 EmitBranch(true_block, false_block, equal); 1922 EmitBranch(true_block, false_block, equal);
1923 } else { 1923 } else {
1924 Handle<Object> other_nil_value = instr->nil() == kNullValue ? 1924 Handle<Object> other_nil_value = instr->nil() == kNullValue ?
1925 factory()->undefined_value() : 1925 factory()->undefined_value() :
1926 factory()->null_value(); 1926 factory()->null_value();
1927 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1927 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1928 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1928 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1929 __ j(equal, true_label); 1929 __ j(equal, true_label);
1930 __ cmp(reg, other_nil_value); 1930 __ cmp(reg, other_nil_value);
1931 __ j(equal, true_label); 1931 __ j(equal, true_label);
1932 __ JumpIfSmi(reg, false_label); 1932 __ JumpIfSmi(reg, false_label);
1933 // Check for undetectable objects by looking in the bit field in 1933 // Check for undetectable objects by looking in the bit field in
1934 // the map. The object has already been smi checked. 1934 // the map. The object has already been smi checked.
1935 Register scratch = ToRegister(instr->TempAt(0)); 1935 Register scratch = ToRegister(instr->temp());
1936 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1936 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1937 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1937 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1938 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1938 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1939 EmitBranch(true_block, false_block, not_zero); 1939 EmitBranch(true_block, false_block, not_zero);
1940 } 1940 }
1941 } 1941 }
1942 1942
1943 1943
1944 Condition LCodeGen::EmitIsObject(Register input, 1944 Condition LCodeGen::EmitIsObject(Register input,
1945 Register temp1, 1945 Register temp1,
(...skipping 12 matching lines...) Expand all
1958 1958
1959 __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset)); 1959 __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset));
1960 __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 1960 __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
1961 __ j(below, is_not_object); 1961 __ j(below, is_not_object);
1962 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 1962 __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
1963 return below_equal; 1963 return below_equal;
1964 } 1964 }
1965 1965
1966 1966
1967 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1967 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1968 Register reg = ToRegister(instr->InputAt(0)); 1968 Register reg = ToRegister(instr->value());
1969 Register temp = ToRegister(instr->TempAt(0)); 1969 Register temp = ToRegister(instr->temp());
1970 1970
1971 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1971 int true_block = chunk_->LookupDestination(instr->true_block_id());
1972 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1972 int false_block = chunk_->LookupDestination(instr->false_block_id());
1973 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1973 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1974 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1974 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1975 1975
1976 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label); 1976 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
1977 1977
1978 EmitBranch(true_block, false_block, true_cond); 1978 EmitBranch(true_block, false_block, true_cond);
1979 } 1979 }
1980 1980
1981 1981
1982 Condition LCodeGen::EmitIsString(Register input, 1982 Condition LCodeGen::EmitIsString(Register input,
1983 Register temp1, 1983 Register temp1,
1984 Label* is_not_string) { 1984 Label* is_not_string) {
1985 __ JumpIfSmi(input, is_not_string); 1985 __ JumpIfSmi(input, is_not_string);
1986 1986
1987 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 1987 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
1988 1988
1989 return cond; 1989 return cond;
1990 } 1990 }
1991 1991
1992 1992
1993 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 1993 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
1994 Register reg = ToRegister(instr->InputAt(0)); 1994 Register reg = ToRegister(instr->value());
1995 Register temp = ToRegister(instr->TempAt(0)); 1995 Register temp = ToRegister(instr->temp());
1996 1996
1997 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1997 int true_block = chunk_->LookupDestination(instr->true_block_id());
1998 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1998 int false_block = chunk_->LookupDestination(instr->false_block_id());
1999 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1999 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2000 2000
2001 Condition true_cond = EmitIsString(reg, temp, false_label); 2001 Condition true_cond = EmitIsString(reg, temp, false_label);
2002 2002
2003 EmitBranch(true_block, false_block, true_cond); 2003 EmitBranch(true_block, false_block, true_cond);
2004 } 2004 }
2005 2005
2006 2006
2007 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2007 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2008 Operand input = ToOperand(instr->InputAt(0)); 2008 Operand input = ToOperand(instr->value());
2009 2009
2010 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2010 int true_block = chunk_->LookupDestination(instr->true_block_id());
2011 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2011 int false_block = chunk_->LookupDestination(instr->false_block_id());
2012 2012
2013 __ test(input, Immediate(kSmiTagMask)); 2013 __ test(input, Immediate(kSmiTagMask));
2014 EmitBranch(true_block, false_block, zero); 2014 EmitBranch(true_block, false_block, zero);
2015 } 2015 }
2016 2016
2017 2017
2018 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2018 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2019 Register input = ToRegister(instr->InputAt(0)); 2019 Register input = ToRegister(instr->value());
2020 Register temp = ToRegister(instr->TempAt(0)); 2020 Register temp = ToRegister(instr->temp());
2021 2021
2022 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2022 int true_block = chunk_->LookupDestination(instr->true_block_id());
2023 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2023 int false_block = chunk_->LookupDestination(instr->false_block_id());
2024 2024
2025 STATIC_ASSERT(kSmiTag == 0); 2025 STATIC_ASSERT(kSmiTag == 0);
2026 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 2026 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2027 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 2027 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
2028 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 2028 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
2029 1 << Map::kIsUndetectable); 2029 1 << Map::kIsUndetectable);
2030 EmitBranch(true_block, false_block, not_zero); 2030 EmitBranch(true_block, false_block, not_zero);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 InstanceType to = instr->to(); 2080 InstanceType to = instr->to();
2081 if (from == to) return equal; 2081 if (from == to) return equal;
2082 if (to == LAST_TYPE) return above_equal; 2082 if (to == LAST_TYPE) return above_equal;
2083 if (from == FIRST_TYPE) return below_equal; 2083 if (from == FIRST_TYPE) return below_equal;
2084 UNREACHABLE(); 2084 UNREACHABLE();
2085 return equal; 2085 return equal;
2086 } 2086 }
2087 2087
2088 2088
2089 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2089 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2090 Register input = ToRegister(instr->InputAt(0)); 2090 Register input = ToRegister(instr->value());
2091 Register temp = ToRegister(instr->TempAt(0)); 2091 Register temp = ToRegister(instr->temp());
2092 2092
2093 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2093 int true_block = chunk_->LookupDestination(instr->true_block_id());
2094 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2094 int false_block = chunk_->LookupDestination(instr->false_block_id());
2095 2095
2096 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2096 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2097 2097
2098 __ JumpIfSmi(input, false_label); 2098 __ JumpIfSmi(input, false_label);
2099 2099
2100 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 2100 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2101 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2101 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
2102 } 2102 }
2103 2103
2104 2104
2105 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2105 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2106 Register input = ToRegister(instr->InputAt(0)); 2106 Register input = ToRegister(instr->value());
2107 Register result = ToRegister(instr->result()); 2107 Register result = ToRegister(instr->result());
2108 2108
2109 __ AbortIfNotString(input); 2109 __ AbortIfNotString(input);
2110 2110
2111 __ mov(result, FieldOperand(input, String::kHashFieldOffset)); 2111 __ mov(result, FieldOperand(input, String::kHashFieldOffset));
2112 __ IndexFromHash(result, result); 2112 __ IndexFromHash(result, result);
2113 } 2113 }
2114 2114
2115 2115
2116 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2116 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2117 LHasCachedArrayIndexAndBranch* instr) { 2117 LHasCachedArrayIndexAndBranch* instr) {
2118 Register input = ToRegister(instr->InputAt(0)); 2118 Register input = ToRegister(instr->value());
2119 2119
2120 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2120 int true_block = chunk_->LookupDestination(instr->true_block_id());
2121 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2121 int false_block = chunk_->LookupDestination(instr->false_block_id());
2122 2122
2123 __ test(FieldOperand(input, String::kHashFieldOffset), 2123 __ test(FieldOperand(input, String::kHashFieldOffset),
2124 Immediate(String::kContainsCachedArrayIndexMask)); 2124 Immediate(String::kContainsCachedArrayIndexMask));
2125 EmitBranch(true_block, false_block, equal); 2125 EmitBranch(true_block, false_block, equal);
2126 } 2126 }
2127 2127
2128 2128
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 // booted. This routine isn't expected to work for random API-created 2185 // booted. This routine isn't expected to work for random API-created
2186 // classes and it doesn't have to because you can't access it with natives 2186 // classes and it doesn't have to because you can't access it with natives
2187 // syntax. Since both sides are symbols it is sufficient to use an identity 2187 // syntax. Since both sides are symbols it is sufficient to use an identity
2188 // comparison. 2188 // comparison.
2189 __ cmp(temp, class_name); 2189 __ cmp(temp, class_name);
2190 // End with the answer in the z flag. 2190 // End with the answer in the z flag.
2191 } 2191 }
2192 2192
2193 2193
2194 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2194 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2195 Register input = ToRegister(instr->InputAt(0)); 2195 Register input = ToRegister(instr->value());
2196 Register temp = ToRegister(instr->TempAt(0)); 2196 Register temp = ToRegister(instr->temp());
2197 Register temp2 = ToRegister(instr->TempAt(1)); 2197 Register temp2 = ToRegister(instr->temp2());
2198 2198
2199 Handle<String> class_name = instr->hydrogen()->class_name(); 2199 Handle<String> class_name = instr->hydrogen()->class_name();
2200 2200
2201 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2201 int true_block = chunk_->LookupDestination(instr->true_block_id());
2202 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2202 int false_block = chunk_->LookupDestination(instr->false_block_id());
2203 2203
2204 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2204 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2205 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2205 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2206 2206
2207 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2207 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2208 2208
2209 EmitBranch(true_block, false_block, equal); 2209 EmitBranch(true_block, false_block, equal);
2210 } 2210 }
2211 2211
2212 2212
2213 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2213 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2214 Register reg = ToRegister(instr->InputAt(0)); 2214 Register reg = ToRegister(instr->value());
2215 int true_block = instr->true_block_id(); 2215 int true_block = instr->true_block_id();
2216 int false_block = instr->false_block_id(); 2216 int false_block = instr->false_block_id();
2217 2217
2218 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2218 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2219 EmitBranch(true_block, false_block, equal); 2219 EmitBranch(true_block, false_block, equal);
2220 } 2220 }
2221 2221
2222 2222
2223 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2223 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2224 // Object and function are in fixed registers defined by the stub. 2224 // Object and function are in fixed registers defined by the stub.
(...skipping 25 matching lines...) Expand all
2250 Label* map_check() { return &map_check_; } 2250 Label* map_check() { return &map_check_; }
2251 private: 2251 private:
2252 LInstanceOfKnownGlobal* instr_; 2252 LInstanceOfKnownGlobal* instr_;
2253 Label map_check_; 2253 Label map_check_;
2254 }; 2254 };
2255 2255
2256 DeferredInstanceOfKnownGlobal* deferred; 2256 DeferredInstanceOfKnownGlobal* deferred;
2257 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2257 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2258 2258
2259 Label done, false_result; 2259 Label done, false_result;
2260 Register object = ToRegister(instr->InputAt(1)); 2260 Register object = ToRegister(instr->value());
2261 Register temp = ToRegister(instr->TempAt(0)); 2261 Register temp = ToRegister(instr->temp());
2262 2262
2263 // A Smi is not an instance of anything. 2263 // A Smi is not an instance of anything.
2264 __ JumpIfSmi(object, &false_result); 2264 __ JumpIfSmi(object, &false_result);
2265 2265
2266 // This is the inlined call site instanceof cache. The two occurences of the 2266 // This is the inlined call site instanceof cache. The two occurences of the
2267 // hole value will be patched to the last map/result pair generated by the 2267 // hole value will be patched to the last map/result pair generated by the
2268 // instanceof stub. 2268 // instanceof stub.
2269 Label cache_miss; 2269 Label cache_miss;
2270 Register map = ToRegister(instr->TempAt(0)); 2270 Register map = ToRegister(instr->temp());
2271 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 2271 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
2272 __ bind(deferred->map_check()); // Label for calculating code patching. 2272 __ bind(deferred->map_check()); // Label for calculating code patching.
2273 Handle<JSGlobalPropertyCell> cache_cell = 2273 Handle<JSGlobalPropertyCell> cache_cell =
2274 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value()); 2274 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
2275 __ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map. 2275 __ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map.
2276 __ j(not_equal, &cache_miss, Label::kNear); 2276 __ j(not_equal, &cache_miss, Label::kNear);
2277 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. 2277 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
2278 __ jmp(&done); 2278 __ jmp(&done);
2279 2279
2280 // The inlined call site cache did not match. Check for null and string 2280 // The inlined call site cache did not match. Check for null and string
(...skipping 30 matching lines...) Expand all
2311 flags = static_cast<InstanceofStub::Flags>( 2311 flags = static_cast<InstanceofStub::Flags>(
2312 flags | InstanceofStub::kCallSiteInlineCheck); 2312 flags | InstanceofStub::kCallSiteInlineCheck);
2313 flags = static_cast<InstanceofStub::Flags>( 2313 flags = static_cast<InstanceofStub::Flags>(
2314 flags | InstanceofStub::kReturnTrueFalseObject); 2314 flags | InstanceofStub::kReturnTrueFalseObject);
2315 InstanceofStub stub(flags); 2315 InstanceofStub stub(flags);
2316 2316
2317 // Get the temp register reserved by the instruction. This needs to be a 2317 // Get the temp register reserved by the instruction. This needs to be a
2318 // register which is pushed last by PushSafepointRegisters as top of the 2318 // register which is pushed last by PushSafepointRegisters as top of the
2319 // stack is used to pass the offset to the location of the map check to 2319 // stack is used to pass the offset to the location of the map check to
2320 // the stub. 2320 // the stub.
2321 Register temp = ToRegister(instr->TempAt(0)); 2321 Register temp = ToRegister(instr->temp());
2322 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 2322 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
2323 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2323 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2324 static const int kAdditionalDelta = 13; 2324 static const int kAdditionalDelta = 13;
2325 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2325 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2326 __ mov(temp, Immediate(delta)); 2326 __ mov(temp, Immediate(delta));
2327 __ StoreToSafepointRegisterSlot(temp, temp); 2327 __ StoreToSafepointRegisterSlot(temp, temp);
2328 CallCodeGeneric(stub.GetCode(), 2328 CallCodeGeneric(stub.GetCode(),
2329 RelocInfo::CODE_TARGET, 2329 RelocInfo::CODE_TARGET,
2330 instr, 2330 instr,
2331 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2331 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2478 } else { 2478 } else {
2479 __ j(not_equal, &skip_assignment, Label::kNear); 2479 __ j(not_equal, &skip_assignment, Label::kNear);
2480 } 2480 }
2481 } 2481 }
2482 2482
2483 __ mov(target, value); 2483 __ mov(target, value);
2484 if (instr->hydrogen()->NeedsWriteBarrier()) { 2484 if (instr->hydrogen()->NeedsWriteBarrier()) {
2485 HType type = instr->hydrogen()->value()->type(); 2485 HType type = instr->hydrogen()->value()->type();
2486 SmiCheck check_needed = 2486 SmiCheck check_needed =
2487 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2487 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2488 Register temp = ToRegister(instr->TempAt(0)); 2488 Register temp = ToRegister(instr->temp());
2489 int offset = Context::SlotOffset(instr->slot_index()); 2489 int offset = Context::SlotOffset(instr->slot_index());
2490 __ RecordWriteContextSlot(context, 2490 __ RecordWriteContextSlot(context,
2491 offset, 2491 offset,
2492 value, 2492 value,
2493 temp, 2493 temp,
2494 kSaveFPRegs, 2494 kSaveFPRegs,
2495 EMIT_REMEMBERED_SET, 2495 EMIT_REMEMBERED_SET,
2496 check_needed); 2496 check_needed);
2497 } 2497 }
2498 2498
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 ASSERT(ToRegister(instr->result()).is(eax)); 2643 ASSERT(ToRegister(instr->result()).is(eax));
2644 2644
2645 __ mov(ecx, instr->name()); 2645 __ mov(ecx, instr->name());
2646 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2646 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2647 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2647 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2648 } 2648 }
2649 2649
2650 2650
2651 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 2651 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2652 Register function = ToRegister(instr->function()); 2652 Register function = ToRegister(instr->function());
2653 Register temp = ToRegister(instr->TempAt(0)); 2653 Register temp = ToRegister(instr->temp());
2654 Register result = ToRegister(instr->result()); 2654 Register result = ToRegister(instr->result());
2655 2655
2656 // Check that the function really is a function. 2656 // Check that the function really is a function.
2657 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 2657 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
2658 DeoptimizeIf(not_equal, instr->environment()); 2658 DeoptimizeIf(not_equal, instr->environment());
2659 2659
2660 // Check whether the function has an instance prototype. 2660 // Check whether the function has an instance prototype.
2661 Label non_instance; 2661 Label non_instance;
2662 __ test_b(FieldOperand(result, Map::kBitFieldOffset), 2662 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
2663 1 << Map::kHasNonInstancePrototype); 2663 1 << Map::kHasNonInstancePrototype);
(...skipping 21 matching lines...) Expand all
2685 __ bind(&non_instance); 2685 __ bind(&non_instance);
2686 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 2686 __ mov(result, FieldOperand(result, Map::kConstructorOffset));
2687 2687
2688 // All done. 2688 // All done.
2689 __ bind(&done); 2689 __ bind(&done);
2690 } 2690 }
2691 2691
2692 2692
2693 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2693 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2694 Register result = ToRegister(instr->result()); 2694 Register result = ToRegister(instr->result());
2695 Register input = ToRegister(instr->InputAt(0)); 2695 Register input = ToRegister(instr->object());
2696 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); 2696 __ mov(result, FieldOperand(input, JSObject::kElementsOffset));
2697 if (FLAG_debug_code) { 2697 if (FLAG_debug_code) {
2698 Label done, ok, fail; 2698 Label done, ok, fail;
2699 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2699 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2700 Immediate(factory()->fixed_array_map())); 2700 Immediate(factory()->fixed_array_map()));
2701 __ j(equal, &done, Label::kNear); 2701 __ j(equal, &done, Label::kNear);
2702 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2702 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2703 Immediate(factory()->fixed_cow_array_map())); 2703 Immediate(factory()->fixed_cow_array_map()));
2704 __ j(equal, &done, Label::kNear); 2704 __ j(equal, &done, Label::kNear);
2705 Register temp((result.is(eax)) ? ebx : eax); 2705 Register temp((result.is(eax)) ? ebx : eax);
(...skipping 15 matching lines...) Expand all
2721 __ bind(&ok); 2721 __ bind(&ok);
2722 __ pop(temp); 2722 __ pop(temp);
2723 __ bind(&done); 2723 __ bind(&done);
2724 } 2724 }
2725 } 2725 }
2726 2726
2727 2727
2728 void LCodeGen::DoLoadExternalArrayPointer( 2728 void LCodeGen::DoLoadExternalArrayPointer(
2729 LLoadExternalArrayPointer* instr) { 2729 LLoadExternalArrayPointer* instr) {
2730 Register result = ToRegister(instr->result()); 2730 Register result = ToRegister(instr->result());
2731 Register input = ToRegister(instr->InputAt(0)); 2731 Register input = ToRegister(instr->object());
2732 __ mov(result, FieldOperand(input, 2732 __ mov(result, FieldOperand(input,
2733 ExternalArray::kExternalPointerOffset)); 2733 ExternalArray::kExternalPointerOffset));
2734 } 2734 }
2735 2735
2736 2736
2737 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2737 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2738 Register arguments = ToRegister(instr->arguments()); 2738 Register arguments = ToRegister(instr->arguments());
2739 Register length = ToRegister(instr->length()); 2739 Register length = ToRegister(instr->length());
2740 Operand index = ToOperand(instr->index()); 2740 Operand index = ToOperand(instr->index());
2741 Register result = ToRegister(instr->result()); 2741 Register result = ToRegister(instr->result());
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2934 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2934 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2935 2935
2936 // Result is the frame pointer for the frame if not adapted and for the real 2936 // Result is the frame pointer for the frame if not adapted and for the real
2937 // frame below the adaptor frame if adapted. 2937 // frame below the adaptor frame if adapted.
2938 __ bind(&done); 2938 __ bind(&done);
2939 } 2939 }
2940 } 2940 }
2941 2941
2942 2942
2943 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2943 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2944 Operand elem = ToOperand(instr->InputAt(0)); 2944 Operand elem = ToOperand(instr->elements());
2945 Register result = ToRegister(instr->result()); 2945 Register result = ToRegister(instr->result());
2946 2946
2947 Label done; 2947 Label done;
2948 2948
2949 // If no arguments adaptor frame the number of arguments is fixed. 2949 // If no arguments adaptor frame the number of arguments is fixed.
2950 __ cmp(ebp, elem); 2950 __ cmp(ebp, elem);
2951 __ mov(result, Immediate(scope()->num_parameters())); 2951 __ mov(result, Immediate(scope()->num_parameters()));
2952 __ j(equal, &done, Label::kNear); 2952 __ j(equal, &done, Label::kNear);
2953 2953
2954 // Arguments adaptor frame present. Get argument length from there. 2954 // Arguments adaptor frame present. Get argument length from there.
2955 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2955 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2956 __ mov(result, Operand(result, 2956 __ mov(result, Operand(result,
2957 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2957 ArgumentsAdaptorFrameConstants::kLengthOffset));
2958 __ SmiUntag(result); 2958 __ SmiUntag(result);
2959 2959
2960 // Argument length is in result register. 2960 // Argument length is in result register.
2961 __ bind(&done); 2961 __ bind(&done);
2962 } 2962 }
2963 2963
2964 2964
2965 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 2965 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
2966 Register receiver = ToRegister(instr->receiver()); 2966 Register receiver = ToRegister(instr->receiver());
2967 Register function = ToRegister(instr->function()); 2967 Register function = ToRegister(instr->function());
2968 Register scratch = ToRegister(instr->TempAt(0)); 2968 Register scratch = ToRegister(instr->temp());
2969 2969
2970 // If the receiver is null or undefined, we have to pass the global 2970 // If the receiver is null or undefined, we have to pass the global
2971 // object as a receiver to normal functions. Values have to be 2971 // object as a receiver to normal functions. Values have to be
2972 // passed unchanged to builtins and strict-mode functions. 2972 // passed unchanged to builtins and strict-mode functions.
2973 Label global_object, receiver_ok; 2973 Label global_object, receiver_ok;
2974 2974
2975 // Do not transform the receiver to object for strict mode 2975 // Do not transform the receiver to object for strict mode
2976 // functions. 2976 // functions.
2977 __ mov(scratch, 2977 __ mov(scratch,
2978 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 2978 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3046 RecordPosition(pointers->position()); 3046 RecordPosition(pointers->position());
3047 SafepointGenerator safepoint_generator( 3047 SafepointGenerator safepoint_generator(
3048 this, pointers, Safepoint::kLazyDeopt); 3048 this, pointers, Safepoint::kLazyDeopt);
3049 ParameterCount actual(eax); 3049 ParameterCount actual(eax);
3050 __ InvokeFunction(function, actual, CALL_FUNCTION, 3050 __ InvokeFunction(function, actual, CALL_FUNCTION,
3051 safepoint_generator, CALL_AS_METHOD); 3051 safepoint_generator, CALL_AS_METHOD);
3052 } 3052 }
3053 3053
3054 3054
3055 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3055 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3056 LOperand* argument = instr->InputAt(0); 3056 LOperand* argument = instr->value();
3057 EmitPushTaggedOperand(argument); 3057 EmitPushTaggedOperand(argument);
3058 } 3058 }
3059 3059
3060 3060
3061 void LCodeGen::DoDrop(LDrop* instr) { 3061 void LCodeGen::DoDrop(LDrop* instr) {
3062 __ Drop(instr->count()); 3062 __ Drop(instr->count());
3063 } 3063 }
3064 3064
3065 3065
3066 void LCodeGen::DoThisFunction(LThisFunction* instr) { 3066 void LCodeGen::DoThisFunction(LThisFunction* instr) {
(...skipping 10 matching lines...) Expand all
3077 3077
3078 void LCodeGen::DoOuterContext(LOuterContext* instr) { 3078 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3079 Register context = ToRegister(instr->context()); 3079 Register context = ToRegister(instr->context());
3080 Register result = ToRegister(instr->result()); 3080 Register result = ToRegister(instr->result());
3081 __ mov(result, 3081 __ mov(result,
3082 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 3082 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3083 } 3083 }
3084 3084
3085 3085
3086 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3086 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3087 ASSERT(ToRegister(instr->InputAt(0)).is(esi)); 3087 ASSERT(ToRegister(instr->context()).is(esi));
3088 __ push(esi); // The context is the first argument. 3088 __ push(esi); // The context is the first argument.
3089 __ push(Immediate(instr->hydrogen()->pairs())); 3089 __ push(Immediate(instr->hydrogen()->pairs()));
3090 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); 3090 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3091 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3091 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3092 } 3092 }
3093 3093
3094 3094
3095 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3095 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3096 Register context = ToRegister(instr->context()); 3096 Register context = ToRegister(instr->context());
3097 Register result = ToRegister(instr->result()); 3097 Register result = ToRegister(instr->result());
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
3410 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 3410 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
3411 __ sqrtsd(input_reg, input_reg); 3411 __ sqrtsd(input_reg, input_reg);
3412 __ bind(&done); 3412 __ bind(&done);
3413 } 3413 }
3414 3414
3415 3415
3416 void LCodeGen::DoPower(LPower* instr) { 3416 void LCodeGen::DoPower(LPower* instr) {
3417 Representation exponent_type = instr->hydrogen()->right()->representation(); 3417 Representation exponent_type = instr->hydrogen()->right()->representation();
3418 // Having marked this as a call, we can use any registers. 3418 // Having marked this as a call, we can use any registers.
3419 // Just make sure that the input/output registers are the expected ones. 3419 // Just make sure that the input/output registers are the expected ones.
3420 ASSERT(!instr->InputAt(1)->IsDoubleRegister() || 3420 ASSERT(!instr->right()->IsDoubleRegister() ||
3421 ToDoubleRegister(instr->InputAt(1)).is(xmm1)); 3421 ToDoubleRegister(instr->right()).is(xmm1));
3422 ASSERT(!instr->InputAt(1)->IsRegister() || 3422 ASSERT(!instr->right()->IsRegister() ||
3423 ToRegister(instr->InputAt(1)).is(eax)); 3423 ToRegister(instr->right()).is(eax));
3424 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2)); 3424 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
3425 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); 3425 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3426 3426
3427 if (exponent_type.IsTagged()) { 3427 if (exponent_type.IsTagged()) {
3428 Label no_deopt; 3428 Label no_deopt;
3429 __ JumpIfSmi(eax, &no_deopt); 3429 __ JumpIfSmi(eax, &no_deopt);
3430 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); 3430 __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
3431 DeoptimizeIf(not_equal, instr->environment()); 3431 DeoptimizeIf(not_equal, instr->environment());
3432 __ bind(&no_deopt); 3432 __ bind(&no_deopt);
3433 MathPowStub stub(MathPowStub::TAGGED); 3433 MathPowStub stub(MathPowStub::TAGGED);
3434 __ CallStub(&stub); 3434 __ CallStub(&stub);
(...skipping 17 matching lines...) Expand all
3452 virtual LInstruction* instr() { return instr_; } 3452 virtual LInstruction* instr() { return instr_; }
3453 private: 3453 private:
3454 LRandom* instr_; 3454 LRandom* instr_;
3455 }; 3455 };
3456 3456
3457 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3457 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3458 3458
3459 // Having marked this instruction as a call we can use any 3459 // Having marked this instruction as a call we can use any
3460 // registers. 3460 // registers.
3461 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3461 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3462 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 3462 ASSERT(ToRegister(instr->global_object()).is(eax));
3463 // Assert that the register size is indeed the size of each seed. 3463 // Assert that the register size is indeed the size of each seed.
3464 static const int kSeedSize = sizeof(uint32_t); 3464 static const int kSeedSize = sizeof(uint32_t);
3465 STATIC_ASSERT(kPointerSize == kSeedSize); 3465 STATIC_ASSERT(kPointerSize == kSeedSize);
3466 3466
3467 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset)); 3467 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
3468 static const int kRandomSeedOffset = 3468 static const int kRandomSeedOffset =
3469 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3469 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3470 __ mov(ebx, FieldOperand(eax, kRandomSeedOffset)); 3470 __ mov(ebx, FieldOperand(eax, kRandomSeedOffset));
3471 // ebx: FixedArray of the native context's random seeds 3471 // ebx: FixedArray of the native context's random seeds
3472 3472
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 3709
3710 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3710 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3711 Register object = ToRegister(instr->object()); 3711 Register object = ToRegister(instr->object());
3712 Register value = ToRegister(instr->value()); 3712 Register value = ToRegister(instr->value());
3713 int offset = instr->offset(); 3713 int offset = instr->offset();
3714 3714
3715 if (!instr->transition().is_null()) { 3715 if (!instr->transition().is_null()) {
3716 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 3716 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3717 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 3717 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
3718 } else { 3718 } else {
3719 Register temp = ToRegister(instr->TempAt(0)); 3719 Register temp = ToRegister(instr->temp());
3720 Register temp_map = ToRegister(instr->TempAt(1)); 3720 Register temp_map = ToRegister(instr->temp_map());
3721 __ mov(temp_map, instr->transition()); 3721 __ mov(temp_map, instr->transition());
3722 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); 3722 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
3723 // Update the write barrier for the map field. 3723 // Update the write barrier for the map field.
3724 __ RecordWriteField(object, 3724 __ RecordWriteField(object,
3725 HeapObject::kMapOffset, 3725 HeapObject::kMapOffset,
3726 temp_map, 3726 temp_map,
3727 temp, 3727 temp,
3728 kSaveFPRegs, 3728 kSaveFPRegs,
3729 OMIT_REMEMBERED_SET, 3729 OMIT_REMEMBERED_SET,
3730 OMIT_SMI_CHECK); 3730 OMIT_SMI_CHECK);
3731 } 3731 }
3732 } 3732 }
3733 3733
3734 // Do the store. 3734 // Do the store.
3735 HType type = instr->hydrogen()->value()->type(); 3735 HType type = instr->hydrogen()->value()->type();
3736 SmiCheck check_needed = 3736 SmiCheck check_needed =
3737 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3737 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3738 if (instr->is_in_object()) { 3738 if (instr->is_in_object()) {
3739 __ mov(FieldOperand(object, offset), value); 3739 __ mov(FieldOperand(object, offset), value);
3740 if (instr->hydrogen()->NeedsWriteBarrier()) { 3740 if (instr->hydrogen()->NeedsWriteBarrier()) {
3741 Register temp = ToRegister(instr->TempAt(0)); 3741 Register temp = ToRegister(instr->temp());
3742 // Update the write barrier for the object for in-object properties. 3742 // Update the write barrier for the object for in-object properties.
3743 __ RecordWriteField(object, 3743 __ RecordWriteField(object,
3744 offset, 3744 offset,
3745 value, 3745 value,
3746 temp, 3746 temp,
3747 kSaveFPRegs, 3747 kSaveFPRegs,
3748 EMIT_REMEMBERED_SET, 3748 EMIT_REMEMBERED_SET,
3749 check_needed); 3749 check_needed);
3750 } 3750 }
3751 } else { 3751 } else {
3752 Register temp = ToRegister(instr->TempAt(0)); 3752 Register temp = ToRegister(instr->temp());
3753 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 3753 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
3754 __ mov(FieldOperand(temp, offset), value); 3754 __ mov(FieldOperand(temp, offset), value);
3755 if (instr->hydrogen()->NeedsWriteBarrier()) { 3755 if (instr->hydrogen()->NeedsWriteBarrier()) {
3756 // Update the write barrier for the properties array. 3756 // Update the write barrier for the properties array.
3757 // object is used as a scratch register. 3757 // object is used as a scratch register.
3758 __ RecordWriteField(temp, 3758 __ RecordWriteField(temp,
3759 offset, 3759 offset,
3760 value, 3760 value,
3761 object, 3761 object,
3762 kSaveFPRegs, 3762 kSaveFPRegs,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3938 3938
3939 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3939 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3940 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3940 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3941 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3941 : isolate()->builtins()->KeyedStoreIC_Initialize();
3942 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3942 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3943 } 3943 }
3944 3944
3945 3945
3946 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3946 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3947 Register object_reg = ToRegister(instr->object()); 3947 Register object_reg = ToRegister(instr->object());
3948 Register new_map_reg = ToRegister(instr->new_map_reg()); 3948 Register new_map_reg = ToRegister(instr->new_map_temp());
3949 3949
3950 Handle<Map> from_map = instr->original_map(); 3950 Handle<Map> from_map = instr->original_map();
3951 Handle<Map> to_map = instr->transitioned_map(); 3951 Handle<Map> to_map = instr->transitioned_map();
3952 ElementsKind from_kind = from_map->elements_kind(); 3952 ElementsKind from_kind = from_map->elements_kind();
3953 ElementsKind to_kind = to_map->elements_kind(); 3953 ElementsKind to_kind = to_map->elements_kind();
3954 3954
3955 Label not_applicable; 3955 Label not_applicable;
3956 bool is_simple_map_transition = 3956 bool is_simple_map_transition =
3957 IsSimpleMapChangeTransition(from_kind, to_kind); 3957 IsSimpleMapChangeTransition(from_kind, to_kind);
3958 Label::Distance branch_distance = 3958 Label::Distance branch_distance =
3959 is_simple_map_transition ? Label::kNear : Label::kFar; 3959 is_simple_map_transition ? Label::kNear : Label::kFar;
3960 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3960 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3961 __ j(not_equal, &not_applicable, branch_distance); 3961 __ j(not_equal, &not_applicable, branch_distance);
3962 if (is_simple_map_transition) { 3962 if (is_simple_map_transition) {
3963 Register object_reg = ToRegister(instr->object()); 3963 Register object_reg = ToRegister(instr->object());
3964 Handle<Map> map = instr->hydrogen()->transitioned_map(); 3964 Handle<Map> map = instr->hydrogen()->transitioned_map();
3965 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), 3965 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset),
3966 Immediate(map)); 3966 Immediate(map));
3967 // Write barrier. 3967 // Write barrier.
3968 ASSERT_NE(instr->temp_reg(), NULL); 3968 ASSERT_NE(instr->temp(), NULL);
3969 __ RecordWriteForMap(object_reg, to_map, new_map_reg, 3969 __ RecordWriteForMap(object_reg, to_map, new_map_reg,
3970 ToRegister(instr->temp_reg()), 3970 ToRegister(instr->temp()),
3971 kDontSaveFPRegs); 3971 kDontSaveFPRegs);
3972 } else if (IsFastSmiElementsKind(from_kind) && 3972 } else if (IsFastSmiElementsKind(from_kind) &&
3973 IsFastDoubleElementsKind(to_kind)) { 3973 IsFastDoubleElementsKind(to_kind)) {
3974 __ mov(new_map_reg, to_map); 3974 __ mov(new_map_reg, to_map);
3975 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3975 Register fixed_object_reg = ToRegister(instr->temp());
3976 ASSERT(fixed_object_reg.is(edx)); 3976 ASSERT(fixed_object_reg.is(edx));
3977 ASSERT(new_map_reg.is(ebx)); 3977 ASSERT(new_map_reg.is(ebx));
3978 __ mov(fixed_object_reg, object_reg); 3978 __ mov(fixed_object_reg, object_reg);
3979 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3979 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3980 RelocInfo::CODE_TARGET, instr); 3980 RelocInfo::CODE_TARGET, instr);
3981 } else if (IsFastDoubleElementsKind(from_kind) && 3981 } else if (IsFastDoubleElementsKind(from_kind) &&
3982 IsFastObjectElementsKind(to_kind)) { 3982 IsFastObjectElementsKind(to_kind)) {
3983 __ mov(new_map_reg, to_map); 3983 __ mov(new_map_reg, to_map);
3984 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3984 Register fixed_object_reg = ToRegister(instr->temp());
3985 ASSERT(fixed_object_reg.is(edx)); 3985 ASSERT(fixed_object_reg.is(edx));
3986 ASSERT(new_map_reg.is(ebx)); 3986 ASSERT(new_map_reg.is(ebx));
3987 __ mov(fixed_object_reg, object_reg); 3987 __ mov(fixed_object_reg, object_reg);
3988 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3988 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3989 RelocInfo::CODE_TARGET, instr); 3989 RelocInfo::CODE_TARGET, instr);
3990 } else { 3990 } else {
3991 UNREACHABLE(); 3991 UNREACHABLE();
3992 } 3992 }
3993 __ bind(&not_applicable); 3993 __ bind(&not_applicable);
3994 } 3994 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4107 4107
4108 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4108 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4109 EmitPushTaggedOperand(instr->left()); 4109 EmitPushTaggedOperand(instr->left());
4110 EmitPushTaggedOperand(instr->right()); 4110 EmitPushTaggedOperand(instr->right());
4111 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 4111 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
4112 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4112 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4113 } 4113 }
4114 4114
4115 4115
4116 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4116 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4117 LOperand* input = instr->InputAt(0); 4117 LOperand* input = instr->value();
4118 ASSERT(input->IsRegister() || input->IsStackSlot()); 4118 ASSERT(input->IsRegister() || input->IsStackSlot());
4119 LOperand* output = instr->result(); 4119 LOperand* output = instr->result();
4120 ASSERT(output->IsDoubleRegister()); 4120 ASSERT(output->IsDoubleRegister());
4121 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4121 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4122 } 4122 }
4123 4123
4124 4124
4125 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4125 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4126 LOperand* input = instr->InputAt(0); 4126 LOperand* input = instr->value();
4127 LOperand* output = instr->result(); 4127 LOperand* output = instr->result();
4128 LOperand* temp = instr->TempAt(0); 4128 LOperand* temp = instr->temp();
4129 4129
4130 __ LoadUint32(ToDoubleRegister(output), 4130 __ LoadUint32(ToDoubleRegister(output),
4131 ToRegister(input), 4131 ToRegister(input),
4132 ToDoubleRegister(temp)); 4132 ToDoubleRegister(temp));
4133 } 4133 }
4134 4134
4135 4135
4136 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4136 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4137 class DeferredNumberTagI: public LDeferredCode { 4137 class DeferredNumberTagI: public LDeferredCode {
4138 public: 4138 public:
4139 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4139 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4140 : LDeferredCode(codegen), instr_(instr) { } 4140 : LDeferredCode(codegen), instr_(instr) { }
4141 virtual void Generate() { 4141 virtual void Generate() {
4142 codegen()->DoDeferredNumberTagI(instr_, 4142 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32);
4143 instr_->InputAt(0),
4144 SIGNED_INT32);
4145 } 4143 }
4146 virtual LInstruction* instr() { return instr_; } 4144 virtual LInstruction* instr() { return instr_; }
4147 private: 4145 private:
4148 LNumberTagI* instr_; 4146 LNumberTagI* instr_;
4149 }; 4147 };
4150 4148
4151 LOperand* input = instr->InputAt(0); 4149 LOperand* input = instr->value();
4152 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4150 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4153 Register reg = ToRegister(input); 4151 Register reg = ToRegister(input);
4154 4152
4155 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4153 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4156 __ SmiTag(reg); 4154 __ SmiTag(reg);
4157 __ j(overflow, deferred->entry()); 4155 __ j(overflow, deferred->entry());
4158 __ bind(deferred->exit()); 4156 __ bind(deferred->exit());
4159 } 4157 }
4160 4158
4161 4159
4162 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4160 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4163 class DeferredNumberTagU: public LDeferredCode { 4161 class DeferredNumberTagU: public LDeferredCode {
4164 public: 4162 public:
4165 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4163 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4166 : LDeferredCode(codegen), instr_(instr) { } 4164 : LDeferredCode(codegen), instr_(instr) { }
4167 virtual void Generate() { 4165 virtual void Generate() {
4168 codegen()->DoDeferredNumberTagI(instr_, 4166 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32);
4169 instr_->InputAt(0),
4170 UNSIGNED_INT32);
4171 } 4167 }
4172 virtual LInstruction* instr() { return instr_; } 4168 virtual LInstruction* instr() { return instr_; }
4173 private: 4169 private:
4174 LNumberTagU* instr_; 4170 LNumberTagU* instr_;
4175 }; 4171 };
4176 4172
4177 LOperand* input = instr->InputAt(0); 4173 LOperand* input = instr->value();
4178 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4174 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4179 Register reg = ToRegister(input); 4175 Register reg = ToRegister(input);
4180 4176
4181 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4177 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4182 __ cmp(reg, Immediate(Smi::kMaxValue)); 4178 __ cmp(reg, Immediate(Smi::kMaxValue));
4183 __ j(above, deferred->entry()); 4179 __ j(above, deferred->entry());
4184 __ SmiTag(reg); 4180 __ SmiTag(reg);
4185 __ bind(deferred->exit()); 4181 __ bind(deferred->exit());
4186 } 4182 }
4187 4183
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4244 class DeferredNumberTagD: public LDeferredCode { 4240 class DeferredNumberTagD: public LDeferredCode {
4245 public: 4241 public:
4246 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4242 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4247 : LDeferredCode(codegen), instr_(instr) { } 4243 : LDeferredCode(codegen), instr_(instr) { }
4248 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4244 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4249 virtual LInstruction* instr() { return instr_; } 4245 virtual LInstruction* instr() { return instr_; }
4250 private: 4246 private:
4251 LNumberTagD* instr_; 4247 LNumberTagD* instr_;
4252 }; 4248 };
4253 4249
4254 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 4250 XMMRegister input_reg = ToDoubleRegister(instr->value());
4255 Register reg = ToRegister(instr->result()); 4251 Register reg = ToRegister(instr->result());
4256 Register tmp = ToRegister(instr->TempAt(0)); 4252 Register tmp = ToRegister(instr->temp());
4257 4253
4258 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4254 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4259 if (FLAG_inline_new) { 4255 if (FLAG_inline_new) {
4260 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 4256 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
4261 } else { 4257 } else {
4262 __ jmp(deferred->entry()); 4258 __ jmp(deferred->entry());
4263 } 4259 }
4264 __ bind(deferred->exit()); 4260 __ bind(deferred->exit());
4265 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4261 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4266 } 4262 }
(...skipping 14 matching lines...) Expand all
4281 // not have easy access to the local context. 4277 // not have easy access to the local context.
4282 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4278 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4283 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4279 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
4284 RecordSafepointWithRegisters( 4280 RecordSafepointWithRegisters(
4285 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4281 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4286 __ StoreToSafepointRegisterSlot(reg, eax); 4282 __ StoreToSafepointRegisterSlot(reg, eax);
4287 } 4283 }
4288 4284
4289 4285
4290 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4286 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4291 LOperand* input = instr->InputAt(0); 4287 LOperand* input = instr->value();
4292 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4288 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4293 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4289 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4294 __ SmiTag(ToRegister(input)); 4290 __ SmiTag(ToRegister(input));
4295 } 4291 }
4296 4292
4297 4293
4298 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4294 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4299 LOperand* input = instr->InputAt(0); 4295 LOperand* input = instr->value();
4300 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4296 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4301 if (instr->needs_check()) { 4297 if (instr->needs_check()) {
4302 __ test(ToRegister(input), Immediate(kSmiTagMask)); 4298 __ test(ToRegister(input), Immediate(kSmiTagMask));
4303 DeoptimizeIf(not_zero, instr->environment()); 4299 DeoptimizeIf(not_zero, instr->environment());
4304 } else { 4300 } else {
4305 if (FLAG_debug_code) { 4301 if (FLAG_debug_code) {
4306 __ AbortIfNotSmi(ToRegister(input)); 4302 __ AbortIfNotSmi(ToRegister(input));
4307 } 4303 }
4308 } 4304 }
4309 __ SmiUntag(ToRegister(input)); 4305 __ SmiUntag(ToRegister(input));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4358 __ bind(&load_smi); 4354 __ bind(&load_smi);
4359 __ SmiUntag(input_reg); // Untag smi before converting to float. 4355 __ SmiUntag(input_reg); // Untag smi before converting to float.
4360 __ cvtsi2sd(result_reg, Operand(input_reg)); 4356 __ cvtsi2sd(result_reg, Operand(input_reg));
4361 __ SmiTag(input_reg); // Retag smi. 4357 __ SmiTag(input_reg); // Retag smi.
4362 __ bind(&done); 4358 __ bind(&done);
4363 } 4359 }
4364 4360
4365 4361
4366 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4362 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4367 Label done, heap_number; 4363 Label done, heap_number;
4368 Register input_reg = ToRegister(instr->InputAt(0)); 4364 Register input_reg = ToRegister(instr->value());
4369 4365
4370 // Heap number map check. 4366 // Heap number map check.
4371 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 4367 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
4372 factory()->heap_number_map()); 4368 factory()->heap_number_map());
4373 4369
4374 if (instr->truncating()) { 4370 if (instr->truncating()) {
4375 __ j(equal, &heap_number, Label::kNear); 4371 __ j(equal, &heap_number, Label::kNear);
4376 // Check for undefined. Undefined is converted to zero for truncating 4372 // Check for undefined. Undefined is converted to zero for truncating
4377 // conversions. 4373 // conversions.
4378 __ cmp(input_reg, factory()->undefined_value()); 4374 __ cmp(input_reg, factory()->undefined_value());
(...skipping 20 matching lines...) Expand all
4399 DeoptimizeIf(no_condition, instr->environment()); 4395 DeoptimizeIf(no_condition, instr->environment());
4400 4396
4401 // Reserve space for 64 bit answer. 4397 // Reserve space for 64 bit answer.
4402 __ bind(&convert); 4398 __ bind(&convert);
4403 __ sub(Operand(esp), Immediate(kDoubleSize)); 4399 __ sub(Operand(esp), Immediate(kDoubleSize));
4404 // Do conversion, which cannot fail because we checked the exponent. 4400 // Do conversion, which cannot fail because we checked the exponent.
4405 __ fisttp_d(Operand(esp, 0)); 4401 __ fisttp_d(Operand(esp, 0));
4406 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 4402 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
4407 __ add(Operand(esp), Immediate(kDoubleSize)); 4403 __ add(Operand(esp), Immediate(kDoubleSize));
4408 } else { 4404 } else {
4409 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); 4405 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4410 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4406 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4411 __ cvttsd2si(input_reg, Operand(xmm0)); 4407 __ cvttsd2si(input_reg, Operand(xmm0));
4412 __ cmp(input_reg, 0x80000000u); 4408 __ cmp(input_reg, 0x80000000u);
4413 __ j(not_equal, &done); 4409 __ j(not_equal, &done);
4414 // Check if the input was 0x8000000 (kMinInt). 4410 // Check if the input was 0x8000000 (kMinInt).
4415 // If no, then we got an overflow and we deoptimize. 4411 // If no, then we got an overflow and we deoptimize.
4416 ExternalReference min_int = ExternalReference::address_of_min_int(); 4412 ExternalReference min_int = ExternalReference::address_of_min_int();
4417 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 4413 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
4418 __ ucomisd(xmm_temp, xmm0); 4414 __ ucomisd(xmm_temp, xmm0);
4419 DeoptimizeIf(not_equal, instr->environment()); 4415 DeoptimizeIf(not_equal, instr->environment());
4420 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4416 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4421 } 4417 }
4422 } else { 4418 } else {
4423 // Deoptimize if we don't have a heap number. 4419 // Deoptimize if we don't have a heap number.
4424 DeoptimizeIf(not_equal, instr->environment()); 4420 DeoptimizeIf(not_equal, instr->environment());
4425 4421
4426 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); 4422 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4427 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4423 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4428 __ cvttsd2si(input_reg, Operand(xmm0)); 4424 __ cvttsd2si(input_reg, Operand(xmm0));
4429 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 4425 __ cvtsi2sd(xmm_temp, Operand(input_reg));
4430 __ ucomisd(xmm0, xmm_temp); 4426 __ ucomisd(xmm0, xmm_temp);
4431 DeoptimizeIf(not_equal, instr->environment()); 4427 DeoptimizeIf(not_equal, instr->environment());
4432 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4428 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4433 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4429 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4434 __ test(input_reg, Operand(input_reg)); 4430 __ test(input_reg, Operand(input_reg));
4435 __ j(not_zero, &done); 4431 __ j(not_zero, &done);
4436 __ movmskpd(input_reg, xmm0); 4432 __ movmskpd(input_reg, xmm0);
4437 __ and_(input_reg, 1); 4433 __ and_(input_reg, 1);
4438 DeoptimizeIf(not_zero, instr->environment()); 4434 DeoptimizeIf(not_zero, instr->environment());
4439 } 4435 }
4440 } 4436 }
4441 __ bind(&done); 4437 __ bind(&done);
4442 } 4438 }
4443 4439
4444 4440
4445 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4441 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4446 class DeferredTaggedToI: public LDeferredCode { 4442 class DeferredTaggedToI: public LDeferredCode {
4447 public: 4443 public:
4448 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4444 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4449 : LDeferredCode(codegen), instr_(instr) { } 4445 : LDeferredCode(codegen), instr_(instr) { }
4450 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4446 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4451 virtual LInstruction* instr() { return instr_; } 4447 virtual LInstruction* instr() { return instr_; }
4452 private: 4448 private:
4453 LTaggedToI* instr_; 4449 LTaggedToI* instr_;
4454 }; 4450 };
4455 4451
4456 LOperand* input = instr->InputAt(0); 4452 LOperand* input = instr->value();
4457 ASSERT(input->IsRegister()); 4453 ASSERT(input->IsRegister());
4458 ASSERT(input->Equals(instr->result())); 4454 ASSERT(input->Equals(instr->result()));
4459 4455
4460 Register input_reg = ToRegister(input); 4456 Register input_reg = ToRegister(input);
4461 4457
4462 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4458 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4463 4459
4464 // Smi check. 4460 // Smi check.
4465 __ JumpIfNotSmi(input_reg, deferred->entry()); 4461 __ JumpIfNotSmi(input_reg, deferred->entry());
4466 4462
4467 // Smi to int32 conversion 4463 // Smi to int32 conversion
4468 __ SmiUntag(input_reg); // Untag smi. 4464 __ SmiUntag(input_reg); // Untag smi.
4469 4465
4470 __ bind(deferred->exit()); 4466 __ bind(deferred->exit());
4471 } 4467 }
4472 4468
4473 4469
4474 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4470 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4475 LOperand* input = instr->InputAt(0); 4471 LOperand* input = instr->value();
4476 ASSERT(input->IsRegister()); 4472 ASSERT(input->IsRegister());
4477 LOperand* temp = instr->TempAt(0); 4473 LOperand* temp = instr->temp();
4478 ASSERT(temp == NULL || temp->IsRegister()); 4474 ASSERT(temp == NULL || temp->IsRegister());
4479 LOperand* result = instr->result(); 4475 LOperand* result = instr->result();
4480 ASSERT(result->IsDoubleRegister()); 4476 ASSERT(result->IsDoubleRegister());
4481 4477
4482 Register input_reg = ToRegister(input); 4478 Register input_reg = ToRegister(input);
4483 XMMRegister result_reg = ToDoubleRegister(result); 4479 XMMRegister result_reg = ToDoubleRegister(result);
4484 4480
4485 bool deoptimize_on_minus_zero = 4481 bool deoptimize_on_minus_zero =
4486 instr->hydrogen()->deoptimize_on_minus_zero(); 4482 instr->hydrogen()->deoptimize_on_minus_zero();
4487 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg; 4483 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
4488 4484
4489 EmitNumberUntagD(input_reg, 4485 EmitNumberUntagD(input_reg,
4490 temp_reg, 4486 temp_reg,
4491 result_reg, 4487 result_reg,
4492 instr->hydrogen()->deoptimize_on_undefined(), 4488 instr->hydrogen()->deoptimize_on_undefined(),
4493 deoptimize_on_minus_zero, 4489 deoptimize_on_minus_zero,
4494 instr->environment()); 4490 instr->environment());
4495 } 4491 }
4496 4492
4497 4493
4498 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4494 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4499 LOperand* input = instr->InputAt(0); 4495 LOperand* input = instr->value();
4500 ASSERT(input->IsDoubleRegister()); 4496 ASSERT(input->IsDoubleRegister());
4501 LOperand* result = instr->result(); 4497 LOperand* result = instr->result();
4502 ASSERT(result->IsRegister()); 4498 ASSERT(result->IsRegister());
4503 4499
4504 XMMRegister input_reg = ToDoubleRegister(input); 4500 XMMRegister input_reg = ToDoubleRegister(input);
4505 Register result_reg = ToRegister(result); 4501 Register result_reg = ToRegister(result);
4506 4502
4507 if (instr->truncating()) { 4503 if (instr->truncating()) {
4508 // Performs a truncating conversion of a floating point number as used by 4504 // Performs a truncating conversion of a floating point number as used by
4509 // the JS bitwise operations. 4505 // the JS bitwise operations.
(...skipping 17 matching lines...) Expand all
4527 DeoptimizeIf(no_condition, instr->environment()); 4523 DeoptimizeIf(no_condition, instr->environment());
4528 __ bind(&convert); 4524 __ bind(&convert);
4529 // Do conversion, which cannot fail because we checked the exponent. 4525 // Do conversion, which cannot fail because we checked the exponent.
4530 __ fld_d(Operand(esp, 0)); 4526 __ fld_d(Operand(esp, 0));
4531 __ fisttp_d(Operand(esp, 0)); 4527 __ fisttp_d(Operand(esp, 0));
4532 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 4528 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
4533 __ add(Operand(esp), Immediate(kDoubleSize)); 4529 __ add(Operand(esp), Immediate(kDoubleSize));
4534 __ bind(&done); 4530 __ bind(&done);
4535 } else { 4531 } else {
4536 Label done; 4532 Label done;
4537 Register temp_reg = ToRegister(instr->TempAt(0)); 4533 Register temp_reg = ToRegister(instr->temp());
4538 XMMRegister xmm_scratch = xmm0; 4534 XMMRegister xmm_scratch = xmm0;
4539 4535
4540 // If cvttsd2si succeeded, we're done. Otherwise, we attempt 4536 // If cvttsd2si succeeded, we're done. Otherwise, we attempt
4541 // manual conversion. 4537 // manual conversion.
4542 __ j(not_equal, &done, Label::kNear); 4538 __ j(not_equal, &done, Label::kNear);
4543 4539
4544 // Get high 32 bits of the input in result_reg and temp_reg. 4540 // Get high 32 bits of the input in result_reg and temp_reg.
4545 __ pshufd(xmm_scratch, input_reg, 1); 4541 __ pshufd(xmm_scratch, input_reg, 1);
4546 __ movd(Operand(temp_reg), xmm_scratch); 4542 __ movd(Operand(temp_reg), xmm_scratch);
4547 __ mov(result_reg, temp_reg); 4543 __ mov(result_reg, temp_reg);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4606 // deoptimize. 4602 // deoptimize.
4607 __ and_(result_reg, 1); 4603 __ and_(result_reg, 1);
4608 DeoptimizeIf(not_zero, instr->environment()); 4604 DeoptimizeIf(not_zero, instr->environment());
4609 } 4605 }
4610 __ bind(&done); 4606 __ bind(&done);
4611 } 4607 }
4612 } 4608 }
4613 4609
4614 4610
4615 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4611 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4616 LOperand* input = instr->InputAt(0); 4612 LOperand* input = instr->value();
4617 __ test(ToOperand(input), Immediate(kSmiTagMask)); 4613 __ test(ToOperand(input), Immediate(kSmiTagMask));
4618 DeoptimizeIf(not_zero, instr->environment()); 4614 DeoptimizeIf(not_zero, instr->environment());
4619 } 4615 }
4620 4616
4621 4617
4622 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4618 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4623 LOperand* input = instr->InputAt(0); 4619 LOperand* input = instr->value();
4624 __ test(ToOperand(input), Immediate(kSmiTagMask)); 4620 __ test(ToOperand(input), Immediate(kSmiTagMask));
4625 DeoptimizeIf(zero, instr->environment()); 4621 DeoptimizeIf(zero, instr->environment());
4626 } 4622 }
4627 4623
4628 4624
4629 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4625 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4630 Register input = ToRegister(instr->InputAt(0)); 4626 Register input = ToRegister(instr->value());
4631 Register temp = ToRegister(instr->TempAt(0)); 4627 Register temp = ToRegister(instr->temp());
4632 4628
4633 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 4629 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
4634 4630
4635 if (instr->hydrogen()->is_interval_check()) { 4631 if (instr->hydrogen()->is_interval_check()) {
4636 InstanceType first; 4632 InstanceType first;
4637 InstanceType last; 4633 InstanceType last;
4638 instr->hydrogen()->GetCheckInterval(&first, &last); 4634 instr->hydrogen()->GetCheckInterval(&first, &last);
4639 4635
4640 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 4636 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
4641 static_cast<int8_t>(first)); 4637 static_cast<int8_t>(first));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4691 CompareMapMode mode, 4687 CompareMapMode mode,
4692 LEnvironment* env) { 4688 LEnvironment* env) {
4693 Label success; 4689 Label success;
4694 __ CompareMap(reg, map, &success, mode); 4690 __ CompareMap(reg, map, &success, mode);
4695 DeoptimizeIf(not_equal, env); 4691 DeoptimizeIf(not_equal, env);
4696 __ bind(&success); 4692 __ bind(&success);
4697 } 4693 }
4698 4694
4699 4695
4700 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4696 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4701 LOperand* input = instr->InputAt(0); 4697 LOperand* input = instr->value();
4702 ASSERT(input->IsRegister()); 4698 ASSERT(input->IsRegister());
4703 Register reg = ToRegister(input); 4699 Register reg = ToRegister(input);
4704 4700
4705 Label success; 4701 Label success;
4706 SmallMapList* map_set = instr->hydrogen()->map_set(); 4702 SmallMapList* map_set = instr->hydrogen()->map_set();
4707 for (int i = 0; i < map_set->length() - 1; i++) { 4703 for (int i = 0; i < map_set->length() - 1; i++) {
4708 Handle<Map> map = map_set->at(i); 4704 Handle<Map> map = map_set->at(i);
4709 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); 4705 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
4710 __ j(equal, &success); 4706 __ j(equal, &success);
4711 } 4707 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4757 // smi 4753 // smi
4758 __ bind(&is_smi); 4754 __ bind(&is_smi);
4759 __ SmiUntag(input_reg); 4755 __ SmiUntag(input_reg);
4760 __ ClampUint8(input_reg); 4756 __ ClampUint8(input_reg);
4761 4757
4762 __ bind(&done); 4758 __ bind(&done);
4763 } 4759 }
4764 4760
4765 4761
4766 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4762 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4767 Register reg = ToRegister(instr->TempAt(0)); 4763 Register reg = ToRegister(instr->temp());
4768 4764
4769 Handle<JSObject> holder = instr->holder(); 4765 Handle<JSObject> holder = instr->holder();
4770 Handle<JSObject> current_prototype = instr->prototype(); 4766 Handle<JSObject> current_prototype = instr->prototype();
4771 4767
4772 // Load prototype object. 4768 // Load prototype object.
4773 __ LoadHeapObject(reg, current_prototype); 4769 __ LoadHeapObject(reg, current_prototype);
4774 4770
4775 // Check prototype maps up to the holder. 4771 // Check prototype maps up to the holder.
4776 while (!current_prototype.is_identical_to(holder)) { 4772 while (!current_prototype.is_identical_to(holder)) {
4777 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()), 4773 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
(...skipping 19 matching lines...) Expand all
4797 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4793 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4798 virtual LInstruction* instr() { return instr_; } 4794 virtual LInstruction* instr() { return instr_; }
4799 private: 4795 private:
4800 LAllocateObject* instr_; 4796 LAllocateObject* instr_;
4801 }; 4797 };
4802 4798
4803 DeferredAllocateObject* deferred = 4799 DeferredAllocateObject* deferred =
4804 new(zone()) DeferredAllocateObject(this, instr); 4800 new(zone()) DeferredAllocateObject(this, instr);
4805 4801
4806 Register result = ToRegister(instr->result()); 4802 Register result = ToRegister(instr->result());
4807 Register scratch = ToRegister(instr->TempAt(0)); 4803 Register scratch = ToRegister(instr->temp());
4808 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4804 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4809 Handle<Map> initial_map(constructor->initial_map()); 4805 Handle<Map> initial_map(constructor->initial_map());
4810 int instance_size = initial_map->instance_size(); 4806 int instance_size = initial_map->instance_size();
4811 ASSERT(initial_map->pre_allocated_property_fields() + 4807 ASSERT(initial_map->pre_allocated_property_fields() +
4812 initial_map->unused_property_fields() - 4808 initial_map->unused_property_fields() -
4813 initial_map->inobject_properties() == 0); 4809 initial_map->inobject_properties() == 0);
4814 4810
4815 // Allocate memory for the object. The initial map might change when 4811 // Allocate memory for the object. The initial map might change when
4816 // the constructor's prototype changes, but instance size and property 4812 // the constructor's prototype changes, but instance size and property
4817 // counts remain unchanged (if slack tracking finished). 4813 // counts remain unchanged (if slack tracking finished).
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
5116 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 5112 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
5117 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 5113 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
5118 } else { 5114 } else {
5119 FastCloneShallowObjectStub stub(properties_count); 5115 FastCloneShallowObjectStub stub(properties_count);
5120 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 5116 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5121 } 5117 }
5122 } 5118 }
5123 5119
5124 5120
5125 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5121 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5126 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 5122 ASSERT(ToRegister(instr->value()).is(eax));
5127 __ push(eax); 5123 __ push(eax);
5128 CallRuntime(Runtime::kToFastProperties, 1, instr); 5124 CallRuntime(Runtime::kToFastProperties, 1, instr);
5129 } 5125 }
5130 5126
5131 5127
5132 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5128 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5133 ASSERT(ToRegister(instr->context()).is(esi)); 5129 ASSERT(ToRegister(instr->context()).is(esi));
5134 Label materialized; 5130 Label materialized;
5135 // Registers will be used as follows: 5131 // Registers will be used as follows:
5136 // ecx = literals array. 5132 // ecx = literals array.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5196 __ push(Immediate(shared_info)); 5192 __ push(Immediate(shared_info));
5197 __ push(Immediate(pretenure 5193 __ push(Immediate(pretenure
5198 ? factory()->true_value() 5194 ? factory()->true_value()
5199 : factory()->false_value())); 5195 : factory()->false_value()));
5200 CallRuntime(Runtime::kNewClosure, 3, instr); 5196 CallRuntime(Runtime::kNewClosure, 3, instr);
5201 } 5197 }
5202 } 5198 }
5203 5199
5204 5200
5205 void LCodeGen::DoTypeof(LTypeof* instr) { 5201 void LCodeGen::DoTypeof(LTypeof* instr) {
5206 LOperand* input = instr->InputAt(1); 5202 LOperand* input = instr->value();
5207 EmitPushTaggedOperand(input); 5203 EmitPushTaggedOperand(input);
5208 CallRuntime(Runtime::kTypeof, 1, instr); 5204 CallRuntime(Runtime::kTypeof, 1, instr);
5209 } 5205 }
5210 5206
5211 5207
5212 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5208 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5213 Register input = ToRegister(instr->InputAt(0)); 5209 Register input = ToRegister(instr->value());
5214 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5210 int true_block = chunk_->LookupDestination(instr->true_block_id());
5215 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5211 int false_block = chunk_->LookupDestination(instr->false_block_id());
5216 Label* true_label = chunk_->GetAssemblyLabel(true_block); 5212 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5217 Label* false_label = chunk_->GetAssemblyLabel(false_block); 5213 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5218 5214
5219 Condition final_branch_condition = 5215 Condition final_branch_condition =
5220 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); 5216 EmitTypeofIs(true_label, false_label, input, instr->type_literal());
5221 if (final_branch_condition != no_condition) { 5217 if (final_branch_condition != no_condition) {
5222 EmitBranch(true_block, false_block, final_branch_condition); 5218 EmitBranch(true_block, false_block, final_branch_condition);
5223 } 5219 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5287 final_branch_condition = zero; 5283 final_branch_condition = zero;
5288 5284
5289 } else { 5285 } else {
5290 __ jmp(false_label); 5286 __ jmp(false_label);
5291 } 5287 }
5292 return final_branch_condition; 5288 return final_branch_condition;
5293 } 5289 }
5294 5290
5295 5291
5296 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5292 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5297 Register temp = ToRegister(instr->TempAt(0)); 5293 Register temp = ToRegister(instr->temp());
5298 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5294 int true_block = chunk_->LookupDestination(instr->true_block_id());
5299 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5295 int false_block = chunk_->LookupDestination(instr->false_block_id());
5300 5296
5301 EmitIsConstructCall(temp); 5297 EmitIsConstructCall(temp);
5302 EmitBranch(true_block, false_block, equal); 5298 EmitBranch(true_block, false_block, equal);
5303 } 5299 }
5304 5300
5305 5301
5306 void LCodeGen::EmitIsConstructCall(Register temp) { 5302 void LCodeGen::EmitIsConstructCall(Register temp) {
5307 // Get the frame pointer for the calling frame. 5303 // Get the frame pointer for the calling frame.
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
5545 FixedArray::kHeaderSize - kPointerSize)); 5541 FixedArray::kHeaderSize - kPointerSize));
5546 __ bind(&done); 5542 __ bind(&done);
5547 } 5543 }
5548 5544
5549 5545
5550 #undef __ 5546 #undef __
5551 5547
5552 } } // namespace v8::internal 5548 } } // namespace v8::internal
5553 5549
5554 #endif // V8_TARGET_ARCH_IA32 5550 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | src/ia32/lithium-ia32.h » ('j') | src/ia32/lithium-ia32.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698