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

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

Issue 10933087: Consistently use named getters for Lithium operands on x64 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed review comments 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/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 } 811 }
812 812
813 813
814 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 814 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
815 // Nothing to do. 815 // Nothing to do.
816 } 816 }
817 817
818 818
819 void LCodeGen::DoModI(LModI* instr) { 819 void LCodeGen::DoModI(LModI* instr) {
820 if (instr->hydrogen()->HasPowerOf2Divisor()) { 820 if (instr->hydrogen()->HasPowerOf2Divisor()) {
821 Register dividend = ToRegister(instr->InputAt(0)); 821 Register dividend = ToRegister(instr->left());
822 822
823 int32_t divisor = 823 int32_t divisor =
824 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 824 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
825 825
826 if (divisor < 0) divisor = -divisor; 826 if (divisor < 0) divisor = -divisor;
827 827
828 Label positive_dividend, done; 828 Label positive_dividend, done;
829 __ testl(dividend, dividend); 829 __ testl(dividend, dividend);
830 __ j(not_sign, &positive_dividend, Label::kNear); 830 __ j(not_sign, &positive_dividend, Label::kNear);
831 __ negl(dividend); 831 __ negl(dividend);
832 __ andl(dividend, Immediate(divisor - 1)); 832 __ andl(dividend, Immediate(divisor - 1));
833 __ negl(dividend); 833 __ negl(dividend);
834 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 834 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
835 __ j(not_zero, &done, Label::kNear); 835 __ j(not_zero, &done, Label::kNear);
836 DeoptimizeIf(no_condition, instr->environment()); 836 DeoptimizeIf(no_condition, instr->environment());
837 } else { 837 } else {
838 __ jmp(&done, Label::kNear); 838 __ jmp(&done, Label::kNear);
839 } 839 }
840 __ bind(&positive_dividend); 840 __ bind(&positive_dividend);
841 __ andl(dividend, Immediate(divisor - 1)); 841 __ andl(dividend, Immediate(divisor - 1));
842 __ bind(&done); 842 __ bind(&done);
843 } else { 843 } else {
844 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive; 844 Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
845 Register left_reg = ToRegister(instr->InputAt(0)); 845 Register left_reg = ToRegister(instr->left());
846 Register right_reg = ToRegister(instr->InputAt(1)); 846 Register right_reg = ToRegister(instr->right());
847 Register result_reg = ToRegister(instr->result()); 847 Register result_reg = ToRegister(instr->result());
848 848
849 ASSERT(left_reg.is(rax)); 849 ASSERT(left_reg.is(rax));
850 ASSERT(result_reg.is(rdx)); 850 ASSERT(result_reg.is(rdx));
851 ASSERT(!right_reg.is(rax)); 851 ASSERT(!right_reg.is(rax));
852 ASSERT(!right_reg.is(rdx)); 852 ASSERT(!right_reg.is(rdx));
853 853
854 // Check for x % 0. 854 // Check for x % 0.
855 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 855 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
856 __ testl(right_reg, right_reg); 856 __ testl(right_reg, right_reg);
857 DeoptimizeIf(zero, instr->environment()); 857 DeoptimizeIf(zero, instr->environment());
858 } 858 }
859 859
860 __ testl(left_reg, left_reg); 860 __ testl(left_reg, left_reg);
861 __ j(zero, &remainder_eq_dividend, Label::kNear); 861 __ j(zero, &remainder_eq_dividend, Label::kNear);
862 __ j(sign, &slow, Label::kNear); 862 __ j(sign, &slow, Label::kNear);
863 863
864 __ testl(right_reg, right_reg); 864 __ testl(right_reg, right_reg);
865 __ j(not_sign, &both_positive, Label::kNear); 865 __ j(not_sign, &both_positive, Label::kNear);
866 // The sign of the divisor doesn't matter. 866 // The sign of the divisor doesn't matter.
867 __ neg(right_reg); 867 __ neg(right_reg);
868 868
869 __ bind(&both_positive); 869 __ bind(&both_positive);
870 // If the dividend is smaller than the nonnegative 870 // If the dividend is smaller than the nonnegative
871 // divisor, the dividend is the result. 871 // divisor, the dividend is the result.
872 __ cmpl(left_reg, right_reg); 872 __ cmpl(left_reg, right_reg);
873 __ j(less, &remainder_eq_dividend, Label::kNear); 873 __ j(less, &remainder_eq_dividend, Label::kNear);
874 874
875 // Check if the divisor is a PowerOfTwo integer. 875 // Check if the divisor is a PowerOfTwo integer.
876 Register scratch = ToRegister(instr->TempAt(0)); 876 Register scratch = ToRegister(instr->temp());
877 __ movl(scratch, right_reg); 877 __ movl(scratch, right_reg);
878 __ subl(scratch, Immediate(1)); 878 __ subl(scratch, Immediate(1));
879 __ testl(scratch, right_reg); 879 __ testl(scratch, right_reg);
880 __ j(not_zero, &do_subtraction, Label::kNear); 880 __ j(not_zero, &do_subtraction, Label::kNear);
881 __ andl(left_reg, scratch); 881 __ andl(left_reg, scratch);
882 __ jmp(&remainder_eq_dividend, Label::kNear); 882 __ jmp(&remainder_eq_dividend, Label::kNear);
883 883
884 __ bind(&do_subtraction); 884 __ bind(&do_subtraction);
885 const int kUnfolds = 3; 885 const int kUnfolds = 3;
886 // Try a few subtractions of the dividend. 886 // Try a few subtractions of the dividend.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 923
924 __ bind(&remainder_eq_dividend); 924 __ bind(&remainder_eq_dividend);
925 __ movl(result_reg, left_reg); 925 __ movl(result_reg, left_reg);
926 926
927 __ bind(&done); 927 __ bind(&done);
928 } 928 }
929 } 929 }
930 930
931 931
932 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { 932 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
933 ASSERT(instr->InputAt(1)->IsConstantOperand()); 933 ASSERT(instr->right()->IsConstantOperand());
934 934
935 const Register dividend = ToRegister(instr->InputAt(0)); 935 const Register dividend = ToRegister(instr->left());
936 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1))); 936 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
937 const Register result = ToRegister(instr->result()); 937 const Register result = ToRegister(instr->result());
938 938
939 switch (divisor) { 939 switch (divisor) {
940 case 0: 940 case 0:
941 DeoptimizeIf(no_condition, instr->environment()); 941 DeoptimizeIf(no_condition, instr->environment());
942 return; 942 return;
943 943
944 case 1: 944 case 1:
945 if (!result.is(dividend)) { 945 if (!result.is(dividend)) {
946 __ movl(result, dividend); 946 __ movl(result, dividend);
(...skipping 24 matching lines...) Expand all
971 DeoptimizeIf(zero, instr->environment()); 971 DeoptimizeIf(zero, instr->environment());
972 } 972 }
973 __ sar(result, Immediate(power)); 973 __ sar(result, Immediate(power));
974 } else { 974 } else {
975 if (!result.is(dividend)) { 975 if (!result.is(dividend)) {
976 __ movl(result, dividend); 976 __ movl(result, dividend);
977 } 977 }
978 __ sarl(result, Immediate(power)); 978 __ sarl(result, Immediate(power));
979 } 979 }
980 } else { 980 } else {
981 Register reg1 = ToRegister(instr->TempAt(0)); 981 Register reg1 = ToRegister(instr->temp());
982 Register reg2 = ToRegister(instr->result()); 982 Register reg2 = ToRegister(instr->result());
983 983
984 // Find b which: 2^b < divisor_abs < 2^(b+1). 984 // Find b which: 2^b < divisor_abs < 2^(b+1).
985 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 985 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
986 unsigned shift = 32 + b; // Precision +1bit (effectively). 986 unsigned shift = 32 + b; // Precision +1bit (effectively).
987 double multiplier_f = 987 double multiplier_f =
988 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 988 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
989 int64_t multiplier; 989 int64_t multiplier;
990 if (multiplier_f - floor(multiplier_f) < 0.5) { 990 if (multiplier_f - floor(multiplier_f) < 0.5) {
991 multiplier = static_cast<int64_t>(floor(multiplier_f)); 991 multiplier = static_cast<int64_t>(floor(multiplier_f));
(...skipping 14 matching lines...) Expand all
1006 // Result just fit in r64, because it's int32 * uint32. 1006 // Result just fit in r64, because it's int32 * uint32.
1007 __ imul(reg2, reg1); 1007 __ imul(reg2, reg1);
1008 1008
1009 __ addq(reg2, Immediate(1 << 30)); 1009 __ addq(reg2, Immediate(1 << 30));
1010 __ sar(reg2, Immediate(shift)); 1010 __ sar(reg2, Immediate(shift));
1011 } 1011 }
1012 } 1012 }
1013 1013
1014 1014
1015 void LCodeGen::DoDivI(LDivI* instr) { 1015 void LCodeGen::DoDivI(LDivI* instr) {
1016 LOperand* right = instr->InputAt(1); 1016 LOperand* right = instr->right();
1017 ASSERT(ToRegister(instr->result()).is(rax)); 1017 ASSERT(ToRegister(instr->result()).is(rax));
1018 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); 1018 ASSERT(ToRegister(instr->left()).is(rax));
1019 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); 1019 ASSERT(!ToRegister(instr->right()).is(rax));
1020 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); 1020 ASSERT(!ToRegister(instr->right()).is(rdx));
1021 1021
1022 Register left_reg = rax; 1022 Register left_reg = rax;
1023 1023
1024 // Check for x / 0. 1024 // Check for x / 0.
1025 Register right_reg = ToRegister(right); 1025 Register right_reg = ToRegister(right);
1026 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1026 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1027 __ testl(right_reg, right_reg); 1027 __ testl(right_reg, right_reg);
1028 DeoptimizeIf(zero, instr->environment()); 1028 DeoptimizeIf(zero, instr->environment());
1029 } 1029 }
1030 1030
(...skipping 21 matching lines...) Expand all
1052 __ cdq(); 1052 __ cdq();
1053 __ idivl(right_reg); 1053 __ idivl(right_reg);
1054 1054
1055 // Deoptimize if remainder is not 0. 1055 // Deoptimize if remainder is not 0.
1056 __ testl(rdx, rdx); 1056 __ testl(rdx, rdx);
1057 DeoptimizeIf(not_zero, instr->environment()); 1057 DeoptimizeIf(not_zero, instr->environment());
1058 } 1058 }
1059 1059
1060 1060
1061 void LCodeGen::DoMulI(LMulI* instr) { 1061 void LCodeGen::DoMulI(LMulI* instr) {
1062 Register left = ToRegister(instr->InputAt(0)); 1062 Register left = ToRegister(instr->left());
1063 LOperand* right = instr->InputAt(1); 1063 LOperand* right = instr->right();
1064 1064
1065 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1065 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1066 __ movl(kScratchRegister, left); 1066 __ movl(kScratchRegister, left);
1067 } 1067 }
1068 1068
1069 bool can_overflow = 1069 bool can_overflow =
1070 instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1070 instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1071 if (right->IsConstantOperand()) { 1071 if (right->IsConstantOperand()) {
1072 int right_value = ToInteger32(LConstantOperand::cast(right)); 1072 int right_value = ToInteger32(LConstantOperand::cast(right));
1073 if (right_value == -1) { 1073 if (right_value == -1) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 // Test the non-zero operand for negative sign. 1135 // Test the non-zero operand for negative sign.
1136 __ orl(kScratchRegister, ToRegister(right)); 1136 __ orl(kScratchRegister, ToRegister(right));
1137 DeoptimizeIf(sign, instr->environment()); 1137 DeoptimizeIf(sign, instr->environment());
1138 } 1138 }
1139 __ bind(&done); 1139 __ bind(&done);
1140 } 1140 }
1141 } 1141 }
1142 1142
1143 1143
1144 void LCodeGen::DoBitI(LBitI* instr) { 1144 void LCodeGen::DoBitI(LBitI* instr) {
1145 LOperand* left = instr->InputAt(0); 1145 LOperand* left = instr->left();
1146 LOperand* right = instr->InputAt(1); 1146 LOperand* right = instr->right();
1147 ASSERT(left->Equals(instr->result())); 1147 ASSERT(left->Equals(instr->result()));
1148 ASSERT(left->IsRegister()); 1148 ASSERT(left->IsRegister());
1149 1149
1150 if (right->IsConstantOperand()) { 1150 if (right->IsConstantOperand()) {
1151 int right_operand = ToInteger32(LConstantOperand::cast(right)); 1151 int right_operand = ToInteger32(LConstantOperand::cast(right));
1152 switch (instr->op()) { 1152 switch (instr->op()) {
1153 case Token::BIT_AND: 1153 case Token::BIT_AND:
1154 __ andl(ToRegister(left), Immediate(right_operand)); 1154 __ andl(ToRegister(left), Immediate(right_operand));
1155 break; 1155 break;
1156 case Token::BIT_OR: 1156 case Token::BIT_OR:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 break; 1192 break;
1193 default: 1193 default:
1194 UNREACHABLE(); 1194 UNREACHABLE();
1195 break; 1195 break;
1196 } 1196 }
1197 } 1197 }
1198 } 1198 }
1199 1199
1200 1200
1201 void LCodeGen::DoShiftI(LShiftI* instr) { 1201 void LCodeGen::DoShiftI(LShiftI* instr) {
1202 LOperand* left = instr->InputAt(0); 1202 LOperand* left = instr->left();
1203 LOperand* right = instr->InputAt(1); 1203 LOperand* right = instr->right();
1204 ASSERT(left->Equals(instr->result())); 1204 ASSERT(left->Equals(instr->result()));
1205 ASSERT(left->IsRegister()); 1205 ASSERT(left->IsRegister());
1206 if (right->IsRegister()) { 1206 if (right->IsRegister()) {
1207 ASSERT(ToRegister(right).is(rcx)); 1207 ASSERT(ToRegister(right).is(rcx));
1208 1208
1209 switch (instr->op()) { 1209 switch (instr->op()) {
1210 case Token::SAR: 1210 case Token::SAR:
1211 __ sarl_cl(ToRegister(left)); 1211 __ sarl_cl(ToRegister(left));
1212 break; 1212 break;
1213 case Token::SHR: 1213 case Token::SHR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 break; 1248 break;
1249 default: 1249 default:
1250 UNREACHABLE(); 1250 UNREACHABLE();
1251 break; 1251 break;
1252 } 1252 }
1253 } 1253 }
1254 } 1254 }
1255 1255
1256 1256
1257 void LCodeGen::DoSubI(LSubI* instr) { 1257 void LCodeGen::DoSubI(LSubI* instr) {
1258 LOperand* left = instr->InputAt(0); 1258 LOperand* left = instr->left();
1259 LOperand* right = instr->InputAt(1); 1259 LOperand* right = instr->right();
1260 ASSERT(left->Equals(instr->result())); 1260 ASSERT(left->Equals(instr->result()));
1261 1261
1262 if (right->IsConstantOperand()) { 1262 if (right->IsConstantOperand()) {
1263 __ subl(ToRegister(left), 1263 __ subl(ToRegister(left),
1264 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1264 Immediate(ToInteger32(LConstantOperand::cast(right))));
1265 } else if (right->IsRegister()) { 1265 } else if (right->IsRegister()) {
1266 __ subl(ToRegister(left), ToRegister(right)); 1266 __ subl(ToRegister(left), ToRegister(right));
1267 } else { 1267 } else {
1268 __ subl(ToRegister(left), ToOperand(right)); 1268 __ subl(ToRegister(left), ToOperand(right));
1269 } 1269 }
(...skipping 13 matching lines...) Expand all
1283 void LCodeGen::DoConstantD(LConstantD* instr) { 1283 void LCodeGen::DoConstantD(LConstantD* instr) {
1284 ASSERT(instr->result()->IsDoubleRegister()); 1284 ASSERT(instr->result()->IsDoubleRegister());
1285 XMMRegister res = ToDoubleRegister(instr->result()); 1285 XMMRegister res = ToDoubleRegister(instr->result());
1286 double v = instr->value(); 1286 double v = instr->value();
1287 uint64_t int_val = BitCast<uint64_t, double>(v); 1287 uint64_t int_val = BitCast<uint64_t, double>(v);
1288 // Use xor to produce +0.0 in a fast and compact way, but avoid to 1288 // Use xor to produce +0.0 in a fast and compact way, but avoid to
1289 // do so if the constant is -0.0. 1289 // do so if the constant is -0.0.
1290 if (int_val == 0) { 1290 if (int_val == 0) {
1291 __ xorps(res, res); 1291 __ xorps(res, res);
1292 } else { 1292 } else {
1293 Register tmp = ToRegister(instr->TempAt(0)); 1293 Register tmp = ToRegister(instr->temp());
1294 __ Set(tmp, int_val); 1294 __ Set(tmp, int_val);
1295 __ movq(res, tmp); 1295 __ movq(res, tmp);
1296 } 1296 }
1297 } 1297 }
1298 1298
1299 1299
1300 void LCodeGen::DoConstantT(LConstantT* instr) { 1300 void LCodeGen::DoConstantT(LConstantT* instr) {
1301 Handle<Object> value = instr->value(); 1301 Handle<Object> value = instr->value();
1302 if (value->IsSmi()) { 1302 if (value->IsSmi()) {
1303 __ Move(ToRegister(instr->result()), value); 1303 __ Move(ToRegister(instr->result()), value);
1304 } else { 1304 } else {
1305 __ LoadHeapObject(ToRegister(instr->result()), 1305 __ LoadHeapObject(ToRegister(instr->result()),
1306 Handle<HeapObject>::cast(value)); 1306 Handle<HeapObject>::cast(value));
1307 } 1307 }
1308 } 1308 }
1309 1309
1310 1310
1311 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1311 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1312 Register result = ToRegister(instr->result()); 1312 Register result = ToRegister(instr->result());
1313 Register array = ToRegister(instr->InputAt(0)); 1313 Register array = ToRegister(instr->value());
1314 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); 1314 __ movq(result, FieldOperand(array, JSArray::kLengthOffset));
1315 } 1315 }
1316 1316
1317 1317
1318 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { 1318 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
1319 Register result = ToRegister(instr->result()); 1319 Register result = ToRegister(instr->result());
1320 Register array = ToRegister(instr->InputAt(0)); 1320 Register array = ToRegister(instr->value());
1321 __ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset)); 1321 __ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
1322 } 1322 }
1323 1323
1324 1324
1325 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1325 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1326 Register result = ToRegister(instr->result()); 1326 Register result = ToRegister(instr->result());
1327 Register map = ToRegister(instr->InputAt(0)); 1327 Register map = ToRegister(instr->value());
1328 __ EnumLength(result, map); 1328 __ EnumLength(result, map);
1329 } 1329 }
1330 1330
1331 1331
1332 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1332 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1333 Register result = ToRegister(instr->result()); 1333 Register result = ToRegister(instr->result());
1334 Register input = ToRegister(instr->InputAt(0)); 1334 Register input = ToRegister(instr->value());
1335 1335
1336 // Load map into |result|. 1336 // Load map into |result|.
1337 __ movq(result, FieldOperand(input, HeapObject::kMapOffset)); 1337 __ movq(result, FieldOperand(input, HeapObject::kMapOffset));
1338 // Load the map's "bit field 2" into |result|. We only need the first byte. 1338 // Load the map's "bit field 2" into |result|. We only need the first byte.
1339 __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset)); 1339 __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset));
1340 // Retrieve elements_kind from bit field 2. 1340 // Retrieve elements_kind from bit field 2.
1341 __ and_(result, Immediate(Map::kElementsKindMask)); 1341 __ and_(result, Immediate(Map::kElementsKindMask));
1342 __ shr(result, Immediate(Map::kElementsKindShift)); 1342 __ shr(result, Immediate(Map::kElementsKindShift));
1343 } 1343 }
1344 1344
1345 1345
1346 void LCodeGen::DoValueOf(LValueOf* instr) { 1346 void LCodeGen::DoValueOf(LValueOf* instr) {
1347 Register input = ToRegister(instr->InputAt(0)); 1347 Register input = ToRegister(instr->value());
1348 Register result = ToRegister(instr->result()); 1348 Register result = ToRegister(instr->result());
1349 ASSERT(input.is(result)); 1349 ASSERT(input.is(result));
1350 Label done; 1350 Label done;
1351 // If the object is a smi return the object. 1351 // If the object is a smi return the object.
1352 __ JumpIfSmi(input, &done, Label::kNear); 1352 __ JumpIfSmi(input, &done, Label::kNear);
1353 1353
1354 // If the object is not a value type, return the object. 1354 // If the object is not a value type, return the object.
1355 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister); 1355 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister);
1356 __ j(not_equal, &done, Label::kNear); 1356 __ j(not_equal, &done, Label::kNear);
1357 __ movq(result, FieldOperand(input, JSValue::kValueOffset)); 1357 __ movq(result, FieldOperand(input, JSValue::kValueOffset));
1358 1358
1359 __ bind(&done); 1359 __ bind(&done);
1360 } 1360 }
1361 1361
1362 1362
1363 void LCodeGen::DoDateField(LDateField* instr) { 1363 void LCodeGen::DoDateField(LDateField* instr) {
1364 Register object = ToRegister(instr->InputAt(0)); 1364 Register object = ToRegister(instr->date());
1365 Register result = ToRegister(instr->result()); 1365 Register result = ToRegister(instr->result());
1366 Smi* index = instr->index(); 1366 Smi* index = instr->index();
1367 Label runtime, done, not_date_object; 1367 Label runtime, done, not_date_object;
1368 ASSERT(object.is(result)); 1368 ASSERT(object.is(result));
1369 ASSERT(object.is(rax)); 1369 ASSERT(object.is(rax));
1370 1370
1371 Condition cc = masm()->CheckSmi(object); 1371 Condition cc = masm()->CheckSmi(object);
1372 DeoptimizeIf(cc, instr->environment()); 1372 DeoptimizeIf(cc, instr->environment());
1373 __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister); 1373 __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister);
1374 DeoptimizeIf(not_equal, instr->environment()); 1374 DeoptimizeIf(not_equal, instr->environment());
(...skipping 21 matching lines...) Expand all
1396 __ movq(rsi, index, RelocInfo::NONE); 1396 __ movq(rsi, index, RelocInfo::NONE);
1397 #endif 1397 #endif
1398 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1398 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1399 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1399 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1400 __ bind(&done); 1400 __ bind(&done);
1401 } 1401 }
1402 } 1402 }
1403 1403
1404 1404
1405 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1405 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1406 LOperand* input = instr->InputAt(0); 1406 LOperand* input = instr->value();
1407 ASSERT(input->Equals(instr->result())); 1407 ASSERT(input->Equals(instr->result()));
1408 __ not_(ToRegister(input)); 1408 __ not_(ToRegister(input));
1409 } 1409 }
1410 1410
1411 1411
1412 void LCodeGen::DoThrow(LThrow* instr) { 1412 void LCodeGen::DoThrow(LThrow* instr) {
1413 __ push(ToRegister(instr->InputAt(0))); 1413 __ push(ToRegister(instr->value()));
1414 CallRuntime(Runtime::kThrow, 1, instr); 1414 CallRuntime(Runtime::kThrow, 1, instr);
1415 1415
1416 if (FLAG_debug_code) { 1416 if (FLAG_debug_code) {
1417 Comment("Unreachable code."); 1417 Comment("Unreachable code.");
1418 __ int3(); 1418 __ int3();
1419 } 1419 }
1420 } 1420 }
1421 1421
1422 1422
1423 void LCodeGen::DoAddI(LAddI* instr) { 1423 void LCodeGen::DoAddI(LAddI* instr) {
1424 LOperand* left = instr->InputAt(0); 1424 LOperand* left = instr->left();
1425 LOperand* right = instr->InputAt(1); 1425 LOperand* right = instr->right();
1426 ASSERT(left->Equals(instr->result())); 1426 ASSERT(left->Equals(instr->result()));
1427 1427
1428 if (right->IsConstantOperand()) { 1428 if (right->IsConstantOperand()) {
1429 __ addl(ToRegister(left), 1429 __ addl(ToRegister(left),
1430 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1430 Immediate(ToInteger32(LConstantOperand::cast(right))));
1431 } else if (right->IsRegister()) { 1431 } else if (right->IsRegister()) {
1432 __ addl(ToRegister(left), ToRegister(right)); 1432 __ addl(ToRegister(left), ToRegister(right));
1433 } else { 1433 } else {
1434 __ addl(ToRegister(left), ToOperand(right)); 1434 __ addl(ToRegister(left), ToOperand(right));
1435 } 1435 }
1436 1436
1437 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1437 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1438 DeoptimizeIf(overflow, instr->environment()); 1438 DeoptimizeIf(overflow, instr->environment());
1439 } 1439 }
1440 } 1440 }
1441 1441
1442 1442
1443 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1443 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1444 LOperand* left = instr->InputAt(0); 1444 LOperand* left = instr->left();
1445 LOperand* right = instr->InputAt(1); 1445 LOperand* right = instr->right();
1446 ASSERT(left->Equals(instr->result())); 1446 ASSERT(left->Equals(instr->result()));
1447 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1447 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1448 if (instr->hydrogen()->representation().IsInteger32()) { 1448 if (instr->hydrogen()->representation().IsInteger32()) {
1449 Label return_left; 1449 Label return_left;
1450 Condition condition = (operation == HMathMinMax::kMathMin) 1450 Condition condition = (operation == HMathMinMax::kMathMin)
1451 ? less_equal 1451 ? less_equal
1452 : greater_equal; 1452 : greater_equal;
1453 Register left_reg = ToRegister(left); 1453 Register left_reg = ToRegister(left);
1454 if (right->IsConstantOperand()) { 1454 if (right->IsConstantOperand()) {
1455 Immediate right_imm = 1455 Immediate right_imm =
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 __ j(parity_even, &return_left, Label::kNear); 1500 __ j(parity_even, &return_left, Label::kNear);
1501 __ bind(&return_right); 1501 __ bind(&return_right);
1502 __ movsd(left_reg, right_reg); 1502 __ movsd(left_reg, right_reg);
1503 1503
1504 __ bind(&return_left); 1504 __ bind(&return_left);
1505 } 1505 }
1506 } 1506 }
1507 1507
1508 1508
1509 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1509 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1510 XMMRegister left = ToDoubleRegister(instr->InputAt(0)); 1510 XMMRegister left = ToDoubleRegister(instr->left());
1511 XMMRegister right = ToDoubleRegister(instr->InputAt(1)); 1511 XMMRegister right = ToDoubleRegister(instr->right());
1512 XMMRegister result = ToDoubleRegister(instr->result()); 1512 XMMRegister result = ToDoubleRegister(instr->result());
1513 // All operations except MOD are computed in-place. 1513 // All operations except MOD are computed in-place.
1514 ASSERT(instr->op() == Token::MOD || left.is(result)); 1514 ASSERT(instr->op() == Token::MOD || left.is(result));
1515 switch (instr->op()) { 1515 switch (instr->op()) {
1516 case Token::ADD: 1516 case Token::ADD:
1517 __ addsd(left, right); 1517 __ addsd(left, right);
1518 break; 1518 break;
1519 case Token::SUB: 1519 case Token::SUB:
1520 __ subsd(left, right); 1520 __ subsd(left, right);
1521 break; 1521 break;
(...skipping 13 matching lines...) Expand all
1535 __ movaps(result, xmm0); 1535 __ movaps(result, xmm0);
1536 break; 1536 break;
1537 default: 1537 default:
1538 UNREACHABLE(); 1538 UNREACHABLE();
1539 break; 1539 break;
1540 } 1540 }
1541 } 1541 }
1542 1542
1543 1543
1544 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1544 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1545 ASSERT(ToRegister(instr->InputAt(0)).is(rdx)); 1545 ASSERT(ToRegister(instr->left()).is(rdx));
1546 ASSERT(ToRegister(instr->InputAt(1)).is(rax)); 1546 ASSERT(ToRegister(instr->right()).is(rax));
1547 ASSERT(ToRegister(instr->result()).is(rax)); 1547 ASSERT(ToRegister(instr->result()).is(rax));
1548 1548
1549 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1549 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1550 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1550 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1551 __ nop(); // Signals no inlined code. 1551 __ nop(); // Signals no inlined code.
1552 } 1552 }
1553 1553
1554 1554
1555 int LCodeGen::GetNextEmittedBlock(int block) { 1555 int LCodeGen::GetNextEmittedBlock(int block) {
1556 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1556 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
(...skipping 23 matching lines...) Expand all
1580 } 1580 }
1581 } 1581 }
1582 1582
1583 1583
1584 void LCodeGen::DoBranch(LBranch* instr) { 1584 void LCodeGen::DoBranch(LBranch* instr) {
1585 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1585 int true_block = chunk_->LookupDestination(instr->true_block_id());
1586 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1586 int false_block = chunk_->LookupDestination(instr->false_block_id());
1587 1587
1588 Representation r = instr->hydrogen()->value()->representation(); 1588 Representation r = instr->hydrogen()->value()->representation();
1589 if (r.IsInteger32()) { 1589 if (r.IsInteger32()) {
1590 Register reg = ToRegister(instr->InputAt(0)); 1590 Register reg = ToRegister(instr->value());
1591 __ testl(reg, reg); 1591 __ testl(reg, reg);
1592 EmitBranch(true_block, false_block, not_zero); 1592 EmitBranch(true_block, false_block, not_zero);
1593 } else if (r.IsDouble()) { 1593 } else if (r.IsDouble()) {
1594 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); 1594 XMMRegister reg = ToDoubleRegister(instr->value());
1595 __ xorps(xmm0, xmm0); 1595 __ xorps(xmm0, xmm0);
1596 __ ucomisd(reg, xmm0); 1596 __ ucomisd(reg, xmm0);
1597 EmitBranch(true_block, false_block, not_equal); 1597 EmitBranch(true_block, false_block, not_equal);
1598 } else { 1598 } else {
1599 ASSERT(r.IsTagged()); 1599 ASSERT(r.IsTagged());
1600 Register reg = ToRegister(instr->InputAt(0)); 1600 Register reg = ToRegister(instr->value());
1601 HType type = instr->hydrogen()->value()->type(); 1601 HType type = instr->hydrogen()->value()->type();
1602 if (type.IsBoolean()) { 1602 if (type.IsBoolean()) {
1603 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1603 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1604 EmitBranch(true_block, false_block, equal); 1604 EmitBranch(true_block, false_block, equal);
1605 } else if (type.IsSmi()) { 1605 } else if (type.IsSmi()) {
1606 __ SmiCompare(reg, Smi::FromInt(0)); 1606 __ SmiCompare(reg, Smi::FromInt(0));
1607 EmitBranch(true_block, false_block, not_equal); 1607 EmitBranch(true_block, false_block, not_equal);
1608 } else { 1608 } else {
1609 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1609 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1610 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1610 Label* false_label = chunk_->GetAssemblyLabel(false_block);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 case Token::IN: 1727 case Token::IN:
1728 case Token::INSTANCEOF: 1728 case Token::INSTANCEOF:
1729 default: 1729 default:
1730 UNREACHABLE(); 1730 UNREACHABLE();
1731 } 1731 }
1732 return cond; 1732 return cond;
1733 } 1733 }
1734 1734
1735 1735
1736 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1736 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1737 LOperand* left = instr->InputAt(0); 1737 LOperand* left = instr->left();
1738 LOperand* right = instr->InputAt(1); 1738 LOperand* right = instr->right();
1739 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1739 int false_block = chunk_->LookupDestination(instr->false_block_id());
1740 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1740 int true_block = chunk_->LookupDestination(instr->true_block_id());
1741 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1741 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1742 1742
1743 if (left->IsConstantOperand() && right->IsConstantOperand()) { 1743 if (left->IsConstantOperand() && right->IsConstantOperand()) {
1744 // We can statically evaluate the comparison. 1744 // We can statically evaluate the comparison.
1745 double left_val = ToDouble(LConstantOperand::cast(left)); 1745 double left_val = ToDouble(LConstantOperand::cast(left));
1746 double right_val = ToDouble(LConstantOperand::cast(right)); 1746 double right_val = ToDouble(LConstantOperand::cast(right));
1747 int next_block = 1747 int next_block =
1748 EvalComparison(instr->op(), left_val, right_val) ? true_block 1748 EvalComparison(instr->op(), left_val, right_val) ? true_block
(...skipping 26 matching lines...) Expand all
1775 __ cmpl(ToRegister(left), ToOperand(right)); 1775 __ cmpl(ToRegister(left), ToOperand(right));
1776 } 1776 }
1777 } 1777 }
1778 } 1778 }
1779 EmitBranch(true_block, false_block, cc); 1779 EmitBranch(true_block, false_block, cc);
1780 } 1780 }
1781 } 1781 }
1782 1782
1783 1783
1784 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1784 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1785 Register left = ToRegister(instr->InputAt(0)); 1785 Register left = ToRegister(instr->left());
1786 Register right = ToRegister(instr->InputAt(1)); 1786 Register right = ToRegister(instr->right());
1787 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1787 int false_block = chunk_->LookupDestination(instr->false_block_id());
1788 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1788 int true_block = chunk_->LookupDestination(instr->true_block_id());
1789 1789
1790 __ cmpq(left, right); 1790 __ cmpq(left, right);
1791 EmitBranch(true_block, false_block, equal); 1791 EmitBranch(true_block, false_block, equal);
1792 } 1792 }
1793 1793
1794 1794
1795 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1795 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1796 Register left = ToRegister(instr->InputAt(0)); 1796 Register left = ToRegister(instr->left());
1797 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1797 int true_block = chunk_->LookupDestination(instr->true_block_id());
1798 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1798 int false_block = chunk_->LookupDestination(instr->false_block_id());
1799 1799
1800 __ cmpq(left, Immediate(instr->hydrogen()->right())); 1800 __ cmpq(left, Immediate(instr->hydrogen()->right()));
1801 EmitBranch(true_block, false_block, equal); 1801 EmitBranch(true_block, false_block, equal);
1802 } 1802 }
1803 1803
1804 1804
1805 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 1805 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
1806 Register reg = ToRegister(instr->InputAt(0)); 1806 Register reg = ToRegister(instr->value());
1807 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1807 int false_block = chunk_->LookupDestination(instr->false_block_id());
1808 1808
1809 // If the expression is known to be untagged or a smi, then it's definitely 1809 // If the expression is known to be untagged or a smi, then it's definitely
1810 // not null, and it can't be a an undetectable object. 1810 // not null, and it can't be a an undetectable object.
1811 if (instr->hydrogen()->representation().IsSpecialization() || 1811 if (instr->hydrogen()->representation().IsSpecialization() ||
1812 instr->hydrogen()->type().IsSmi()) { 1812 instr->hydrogen()->type().IsSmi()) {
1813 EmitGoto(false_block); 1813 EmitGoto(false_block);
1814 return; 1814 return;
1815 } 1815 }
1816 1816
1817 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1817 int true_block = chunk_->LookupDestination(instr->true_block_id());
1818 Heap::RootListIndex nil_value = instr->nil() == kNullValue ? 1818 Heap::RootListIndex nil_value = instr->nil() == kNullValue ?
1819 Heap::kNullValueRootIndex : 1819 Heap::kNullValueRootIndex :
1820 Heap::kUndefinedValueRootIndex; 1820 Heap::kUndefinedValueRootIndex;
1821 __ CompareRoot(reg, nil_value); 1821 __ CompareRoot(reg, nil_value);
1822 if (instr->kind() == kStrictEquality) { 1822 if (instr->kind() == kStrictEquality) {
1823 EmitBranch(true_block, false_block, equal); 1823 EmitBranch(true_block, false_block, equal);
1824 } else { 1824 } else {
1825 Heap::RootListIndex other_nil_value = instr->nil() == kNullValue ? 1825 Heap::RootListIndex other_nil_value = instr->nil() == kNullValue ?
1826 Heap::kUndefinedValueRootIndex : 1826 Heap::kUndefinedValueRootIndex :
1827 Heap::kNullValueRootIndex; 1827 Heap::kNullValueRootIndex;
1828 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1828 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1829 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1829 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1830 __ j(equal, true_label); 1830 __ j(equal, true_label);
1831 __ CompareRoot(reg, other_nil_value); 1831 __ CompareRoot(reg, other_nil_value);
1832 __ j(equal, true_label); 1832 __ j(equal, true_label);
1833 __ JumpIfSmi(reg, false_label); 1833 __ JumpIfSmi(reg, false_label);
1834 // Check for undetectable objects by looking in the bit field in 1834 // Check for undetectable objects by looking in the bit field in
1835 // the map. The object has already been smi checked. 1835 // the map. The object has already been smi checked.
1836 Register scratch = ToRegister(instr->TempAt(0)); 1836 Register scratch = ToRegister(instr->temp());
1837 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1837 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1838 __ testb(FieldOperand(scratch, Map::kBitFieldOffset), 1838 __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
1839 Immediate(1 << Map::kIsUndetectable)); 1839 Immediate(1 << Map::kIsUndetectable));
1840 EmitBranch(true_block, false_block, not_zero); 1840 EmitBranch(true_block, false_block, not_zero);
1841 } 1841 }
1842 } 1842 }
1843 1843
1844 1844
1845 Condition LCodeGen::EmitIsObject(Register input, 1845 Condition LCodeGen::EmitIsObject(Register input,
1846 Label* is_not_object, 1846 Label* is_not_object,
(...skipping 14 matching lines...) Expand all
1861 __ movzxbl(kScratchRegister, 1861 __ movzxbl(kScratchRegister,
1862 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 1862 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
1863 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1863 __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
1864 __ j(below, is_not_object); 1864 __ j(below, is_not_object);
1865 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1865 __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
1866 return below_equal; 1866 return below_equal;
1867 } 1867 }
1868 1868
1869 1869
1870 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1870 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1871 Register reg = ToRegister(instr->InputAt(0)); 1871 Register reg = ToRegister(instr->value());
1872 1872
1873 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1873 int true_block = chunk_->LookupDestination(instr->true_block_id());
1874 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1874 int false_block = chunk_->LookupDestination(instr->false_block_id());
1875 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1875 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1876 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1876 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1877 1877
1878 Condition true_cond = EmitIsObject(reg, false_label, true_label); 1878 Condition true_cond = EmitIsObject(reg, false_label, true_label);
1879 1879
1880 EmitBranch(true_block, false_block, true_cond); 1880 EmitBranch(true_block, false_block, true_cond);
1881 } 1881 }
1882 1882
1883 1883
1884 Condition LCodeGen::EmitIsString(Register input, 1884 Condition LCodeGen::EmitIsString(Register input,
1885 Register temp1, 1885 Register temp1,
1886 Label* is_not_string) { 1886 Label* is_not_string) {
1887 __ JumpIfSmi(input, is_not_string); 1887 __ JumpIfSmi(input, is_not_string);
1888 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 1888 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
1889 1889
1890 return cond; 1890 return cond;
1891 } 1891 }
1892 1892
1893 1893
1894 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 1894 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
1895 Register reg = ToRegister(instr->InputAt(0)); 1895 Register reg = ToRegister(instr->value());
1896 Register temp = ToRegister(instr->TempAt(0)); 1896 Register temp = ToRegister(instr->temp());
1897 1897
1898 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1898 int true_block = chunk_->LookupDestination(instr->true_block_id());
1899 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1899 int false_block = chunk_->LookupDestination(instr->false_block_id());
1900 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1900 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1901 1901
1902 Condition true_cond = EmitIsString(reg, temp, false_label); 1902 Condition true_cond = EmitIsString(reg, temp, false_label);
1903 1903
1904 EmitBranch(true_block, false_block, true_cond); 1904 EmitBranch(true_block, false_block, true_cond);
1905 } 1905 }
1906 1906
1907 1907
1908 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1908 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1909 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1909 int true_block = chunk_->LookupDestination(instr->true_block_id());
1910 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1910 int false_block = chunk_->LookupDestination(instr->false_block_id());
1911 1911
1912 Condition is_smi; 1912 Condition is_smi;
1913 if (instr->InputAt(0)->IsRegister()) { 1913 if (instr->value()->IsRegister()) {
1914 Register input = ToRegister(instr->InputAt(0)); 1914 Register input = ToRegister(instr->value());
1915 is_smi = masm()->CheckSmi(input); 1915 is_smi = masm()->CheckSmi(input);
1916 } else { 1916 } else {
1917 Operand input = ToOperand(instr->InputAt(0)); 1917 Operand input = ToOperand(instr->value());
1918 is_smi = masm()->CheckSmi(input); 1918 is_smi = masm()->CheckSmi(input);
1919 } 1919 }
1920 EmitBranch(true_block, false_block, is_smi); 1920 EmitBranch(true_block, false_block, is_smi);
1921 } 1921 }
1922 1922
1923 1923
1924 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 1924 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
1925 Register input = ToRegister(instr->InputAt(0)); 1925 Register input = ToRegister(instr->value());
1926 Register temp = ToRegister(instr->TempAt(0)); 1926 Register temp = ToRegister(instr->temp());
1927 1927
1928 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1928 int true_block = chunk_->LookupDestination(instr->true_block_id());
1929 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1929 int false_block = chunk_->LookupDestination(instr->false_block_id());
1930 1930
1931 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 1931 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
1932 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); 1932 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
1933 __ testb(FieldOperand(temp, Map::kBitFieldOffset), 1933 __ testb(FieldOperand(temp, Map::kBitFieldOffset),
1934 Immediate(1 << Map::kIsUndetectable)); 1934 Immediate(1 << Map::kIsUndetectable));
1935 EmitBranch(true_block, false_block, not_zero); 1935 EmitBranch(true_block, false_block, not_zero);
1936 } 1936 }
(...skipping 28 matching lines...) Expand all
1965 InstanceType to = instr->to(); 1965 InstanceType to = instr->to();
1966 if (from == to) return equal; 1966 if (from == to) return equal;
1967 if (to == LAST_TYPE) return above_equal; 1967 if (to == LAST_TYPE) return above_equal;
1968 if (from == FIRST_TYPE) return below_equal; 1968 if (from == FIRST_TYPE) return below_equal;
1969 UNREACHABLE(); 1969 UNREACHABLE();
1970 return equal; 1970 return equal;
1971 } 1971 }
1972 1972
1973 1973
1974 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1974 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1975 Register input = ToRegister(instr->InputAt(0)); 1975 Register input = ToRegister(instr->value());
1976 1976
1977 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1977 int true_block = chunk_->LookupDestination(instr->true_block_id());
1978 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1978 int false_block = chunk_->LookupDestination(instr->false_block_id());
1979 1979
1980 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1980 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1981 1981
1982 __ JumpIfSmi(input, false_label); 1982 __ JumpIfSmi(input, false_label);
1983 1983
1984 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); 1984 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
1985 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 1985 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1986 } 1986 }
1987 1987
1988 1988
1989 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 1989 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
1990 Register input = ToRegister(instr->InputAt(0)); 1990 Register input = ToRegister(instr->value());
1991 Register result = ToRegister(instr->result()); 1991 Register result = ToRegister(instr->result());
1992 1992
1993 __ AbortIfNotString(input); 1993 __ AbortIfNotString(input);
1994 1994
1995 __ movl(result, FieldOperand(input, String::kHashFieldOffset)); 1995 __ movl(result, FieldOperand(input, String::kHashFieldOffset));
1996 ASSERT(String::kHashShift >= kSmiTagSize); 1996 ASSERT(String::kHashShift >= kSmiTagSize);
1997 __ IndexFromHash(result, result); 1997 __ IndexFromHash(result, result);
1998 } 1998 }
1999 1999
2000 2000
2001 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2001 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2002 LHasCachedArrayIndexAndBranch* instr) { 2002 LHasCachedArrayIndexAndBranch* instr) {
2003 Register input = ToRegister(instr->InputAt(0)); 2003 Register input = ToRegister(instr->value());
2004 2004
2005 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2005 int true_block = chunk_->LookupDestination(instr->true_block_id());
2006 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2006 int false_block = chunk_->LookupDestination(instr->false_block_id());
2007 2007
2008 __ testl(FieldOperand(input, String::kHashFieldOffset), 2008 __ testl(FieldOperand(input, String::kHashFieldOffset),
2009 Immediate(String::kContainsCachedArrayIndexMask)); 2009 Immediate(String::kContainsCachedArrayIndexMask));
2010 EmitBranch(true_block, false_block, equal); 2010 EmitBranch(true_block, false_block, equal);
2011 } 2011 }
2012 2012
2013 2013
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 // classes and it doesn't have to because you can't access it with natives 2073 // classes and it doesn't have to because you can't access it with natives
2074 // syntax. Since both sides are symbols it is sufficient to use an identity 2074 // syntax. Since both sides are symbols it is sufficient to use an identity
2075 // comparison. 2075 // comparison.
2076 ASSERT(class_name->IsSymbol()); 2076 ASSERT(class_name->IsSymbol());
2077 __ Cmp(temp, class_name); 2077 __ Cmp(temp, class_name);
2078 // End with the answer in the z flag. 2078 // End with the answer in the z flag.
2079 } 2079 }
2080 2080
2081 2081
2082 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2082 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2083 Register input = ToRegister(instr->InputAt(0)); 2083 Register input = ToRegister(instr->value());
2084 Register temp = ToRegister(instr->TempAt(0)); 2084 Register temp = ToRegister(instr->temp());
2085 Register temp2 = ToRegister(instr->TempAt(1)); 2085 Register temp2 = ToRegister(instr->temp2());
2086 Handle<String> class_name = instr->hydrogen()->class_name(); 2086 Handle<String> class_name = instr->hydrogen()->class_name();
2087 2087
2088 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2088 int true_block = chunk_->LookupDestination(instr->true_block_id());
2089 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2089 int false_block = chunk_->LookupDestination(instr->false_block_id());
2090 2090
2091 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2091 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2092 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2092 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2093 2093
2094 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2094 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2095 2095
2096 EmitBranch(true_block, false_block, equal); 2096 EmitBranch(true_block, false_block, equal);
2097 } 2097 }
2098 2098
2099 2099
2100 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2100 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2101 Register reg = ToRegister(instr->InputAt(0)); 2101 Register reg = ToRegister(instr->value());
2102 int true_block = instr->true_block_id(); 2102 int true_block = instr->true_block_id();
2103 int false_block = instr->false_block_id(); 2103 int false_block = instr->false_block_id();
2104 2104
2105 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2105 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2106 EmitBranch(true_block, false_block, equal); 2106 EmitBranch(true_block, false_block, equal);
2107 } 2107 }
2108 2108
2109 2109
2110 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2110 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2111 InstanceofStub stub(InstanceofStub::kNoFlags); 2111 InstanceofStub stub(InstanceofStub::kNoFlags);
2112 __ push(ToRegister(instr->InputAt(0))); 2112 __ push(ToRegister(instr->left()));
2113 __ push(ToRegister(instr->InputAt(1))); 2113 __ push(ToRegister(instr->right()));
2114 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2114 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2115 Label true_value, done; 2115 Label true_value, done;
2116 __ testq(rax, rax); 2116 __ testq(rax, rax);
2117 __ j(zero, &true_value, Label::kNear); 2117 __ j(zero, &true_value, Label::kNear);
2118 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 2118 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2119 __ jmp(&done, Label::kNear); 2119 __ jmp(&done, Label::kNear);
2120 __ bind(&true_value); 2120 __ bind(&true_value);
2121 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 2121 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2122 __ bind(&done); 2122 __ bind(&done);
2123 } 2123 }
(...skipping 13 matching lines...) Expand all
2137 private: 2137 private:
2138 LInstanceOfKnownGlobal* instr_; 2138 LInstanceOfKnownGlobal* instr_;
2139 Label map_check_; 2139 Label map_check_;
2140 }; 2140 };
2141 2141
2142 2142
2143 DeferredInstanceOfKnownGlobal* deferred; 2143 DeferredInstanceOfKnownGlobal* deferred;
2144 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2144 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2145 2145
2146 Label done, false_result; 2146 Label done, false_result;
2147 Register object = ToRegister(instr->InputAt(0)); 2147 Register object = ToRegister(instr->value());
2148 2148
2149 // A Smi is not an instance of anything. 2149 // A Smi is not an instance of anything.
2150 __ JumpIfSmi(object, &false_result); 2150 __ JumpIfSmi(object, &false_result);
2151 2151
2152 // This is the inlined call site instanceof cache. The two occurences of the 2152 // This is the inlined call site instanceof cache. The two occurences of the
2153 // hole value will be patched to the last map/result pair generated by the 2153 // hole value will be patched to the last map/result pair generated by the
2154 // instanceof stub. 2154 // instanceof stub.
2155 Label cache_miss; 2155 Label cache_miss;
2156 // Use a temp register to avoid memory operands with variable lengths. 2156 // Use a temp register to avoid memory operands with variable lengths.
2157 Register map = ToRegister(instr->TempAt(0)); 2157 Register map = ToRegister(instr->temp());
2158 __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); 2158 __ movq(map, FieldOperand(object, HeapObject::kMapOffset));
2159 __ bind(deferred->map_check()); // Label for calculating code patching. 2159 __ bind(deferred->map_check()); // Label for calculating code patching.
2160 Handle<JSGlobalPropertyCell> cache_cell = 2160 Handle<JSGlobalPropertyCell> cache_cell =
2161 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value()); 2161 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
2162 __ movq(kScratchRegister, cache_cell, RelocInfo::GLOBAL_PROPERTY_CELL); 2162 __ movq(kScratchRegister, cache_cell, RelocInfo::GLOBAL_PROPERTY_CELL);
2163 __ cmpq(map, Operand(kScratchRegister, 0)); 2163 __ cmpq(map, Operand(kScratchRegister, 0));
2164 __ j(not_equal, &cache_miss, Label::kNear); 2164 __ j(not_equal, &cache_miss, Label::kNear);
2165 // Patched to load either true or false. 2165 // Patched to load either true or false.
2166 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); 2166 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
2167 #ifdef DEBUG 2167 #ifdef DEBUG
(...skipping 22 matching lines...) Expand all
2190 2190
2191 2191
2192 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 2192 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2193 Label* map_check) { 2193 Label* map_check) {
2194 { 2194 {
2195 PushSafepointRegistersScope scope(this); 2195 PushSafepointRegistersScope scope(this);
2196 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( 2196 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
2197 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); 2197 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
2198 InstanceofStub stub(flags); 2198 InstanceofStub stub(flags);
2199 2199
2200 __ push(ToRegister(instr->InputAt(0))); 2200 __ push(ToRegister(instr->value()));
2201 __ PushHeapObject(instr->function()); 2201 __ PushHeapObject(instr->function());
2202 2202
2203 static const int kAdditionalDelta = 10; 2203 static const int kAdditionalDelta = 10;
2204 int delta = 2204 int delta =
2205 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2205 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2206 ASSERT(delta >= 0); 2206 ASSERT(delta >= 0);
2207 __ push_imm32(delta); 2207 __ push_imm32(delta);
2208 2208
2209 // We are pushing three values on the stack but recording a 2209 // We are pushing three values on the stack but recording a
2210 // safepoint with two arguments because stub is going to 2210 // safepoint with two arguments because stub is going to
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2290 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2291 Register value = ToRegister(instr->value()); 2291 Register value = ToRegister(instr->value());
2292 Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell(); 2292 Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
2293 2293
2294 // If the cell we are storing to contains the hole it could have 2294 // If the cell we are storing to contains the hole it could have
2295 // been deleted from the property dictionary. In that case, we need 2295 // been deleted from the property dictionary. In that case, we need
2296 // to update the property details in the property dictionary to mark 2296 // to update the property details in the property dictionary to mark
2297 // it as no longer deleted. We deoptimize in that case. 2297 // it as no longer deleted. We deoptimize in that case.
2298 if (instr->hydrogen()->RequiresHoleCheck()) { 2298 if (instr->hydrogen()->RequiresHoleCheck()) {
2299 // We have a temp because CompareRoot might clobber kScratchRegister. 2299 // We have a temp because CompareRoot might clobber kScratchRegister.
2300 Register cell = ToRegister(instr->TempAt(0)); 2300 Register cell = ToRegister(instr->temp());
2301 ASSERT(!value.is(cell)); 2301 ASSERT(!value.is(cell));
2302 __ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL); 2302 __ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
2303 __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); 2303 __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
2304 DeoptimizeIf(equal, instr->environment()); 2304 DeoptimizeIf(equal, instr->environment());
2305 // Store the value. 2305 // Store the value.
2306 __ movq(Operand(cell, 0), value); 2306 __ movq(Operand(cell, 0), value);
2307 } else { 2307 } else {
2308 // Store the value. 2308 // Store the value.
2309 __ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL); 2309 __ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
2310 __ movq(Operand(kScratchRegister, 0), value); 2310 __ movq(Operand(kScratchRegister, 0), value);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 __ j(not_equal, &skip_assignment); 2358 __ j(not_equal, &skip_assignment);
2359 } 2359 }
2360 } 2360 }
2361 __ movq(target, value); 2361 __ movq(target, value);
2362 2362
2363 if (instr->hydrogen()->NeedsWriteBarrier()) { 2363 if (instr->hydrogen()->NeedsWriteBarrier()) {
2364 HType type = instr->hydrogen()->value()->type(); 2364 HType type = instr->hydrogen()->value()->type();
2365 SmiCheck check_needed = 2365 SmiCheck check_needed =
2366 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2366 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2367 int offset = Context::SlotOffset(instr->slot_index()); 2367 int offset = Context::SlotOffset(instr->slot_index());
2368 Register scratch = ToRegister(instr->TempAt(0)); 2368 Register scratch = ToRegister(instr->temp());
2369 __ RecordWriteContextSlot(context, 2369 __ RecordWriteContextSlot(context,
2370 offset, 2370 offset,
2371 value, 2371 value,
2372 scratch, 2372 scratch,
2373 kSaveFPRegs, 2373 kSaveFPRegs,
2374 EMIT_REMEMBERED_SET, 2374 EMIT_REMEMBERED_SET,
2375 check_needed); 2375 check_needed);
2376 } 2376 }
2377 2377
2378 __ bind(&skip_assignment); 2378 __ bind(&skip_assignment);
2379 } 2379 }
2380 2380
2381 2381
2382 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2382 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2383 Register object = ToRegister(instr->InputAt(0)); 2383 Register object = ToRegister(instr->object());
2384 Register result = ToRegister(instr->result()); 2384 Register result = ToRegister(instr->result());
2385 if (instr->hydrogen()->is_in_object()) { 2385 if (instr->hydrogen()->is_in_object()) {
2386 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); 2386 __ movq(result, FieldOperand(object, instr->hydrogen()->offset()));
2387 } else { 2387 } else {
2388 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2388 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2389 __ movq(result, FieldOperand(result, instr->hydrogen()->offset())); 2389 __ movq(result, FieldOperand(result, instr->hydrogen()->offset()));
2390 } 2390 }
2391 } 2391 }
2392 2392
2393 2393
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 __ bind(&non_instance); 2545 __ bind(&non_instance);
2546 __ movq(result, FieldOperand(result, Map::kConstructorOffset)); 2546 __ movq(result, FieldOperand(result, Map::kConstructorOffset));
2547 2547
2548 // All done. 2548 // All done.
2549 __ bind(&done); 2549 __ bind(&done);
2550 } 2550 }
2551 2551
2552 2552
2553 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2553 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2554 Register result = ToRegister(instr->result()); 2554 Register result = ToRegister(instr->result());
2555 Register input = ToRegister(instr->InputAt(0)); 2555 Register input = ToRegister(instr->object());
2556 __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); 2556 __ movq(result, FieldOperand(input, JSObject::kElementsOffset));
2557 if (FLAG_debug_code) { 2557 if (FLAG_debug_code) {
2558 Label done, ok, fail; 2558 Label done, ok, fail;
2559 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), 2559 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2560 Heap::kFixedArrayMapRootIndex); 2560 Heap::kFixedArrayMapRootIndex);
2561 __ j(equal, &done, Label::kNear); 2561 __ j(equal, &done, Label::kNear);
2562 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), 2562 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2563 Heap::kFixedCOWArrayMapRootIndex); 2563 Heap::kFixedCOWArrayMapRootIndex);
2564 __ j(equal, &done, Label::kNear); 2564 __ j(equal, &done, Label::kNear);
2565 Register temp((result.is(rax)) ? rbx : rax); 2565 Register temp((result.is(rax)) ? rbx : rax);
(...skipping 15 matching lines...) Expand all
2581 __ bind(&ok); 2581 __ bind(&ok);
2582 __ pop(temp); 2582 __ pop(temp);
2583 __ bind(&done); 2583 __ bind(&done);
2584 } 2584 }
2585 } 2585 }
2586 2586
2587 2587
2588 void LCodeGen::DoLoadExternalArrayPointer( 2588 void LCodeGen::DoLoadExternalArrayPointer(
2589 LLoadExternalArrayPointer* instr) { 2589 LLoadExternalArrayPointer* instr) {
2590 Register result = ToRegister(instr->result()); 2590 Register result = ToRegister(instr->result());
2591 Register input = ToRegister(instr->InputAt(0)); 2591 Register input = ToRegister(instr->object());
2592 __ movq(result, FieldOperand(input, 2592 __ movq(result, FieldOperand(input,
2593 ExternalPixelArray::kExternalPointerOffset)); 2593 ExternalPixelArray::kExternalPointerOffset));
2594 } 2594 }
2595 2595
2596 2596
2597 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2597 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2598 Register arguments = ToRegister(instr->arguments()); 2598 Register arguments = ToRegister(instr->arguments());
2599 Register length = ToRegister(instr->length()); 2599 Register length = ToRegister(instr->length());
2600 Register result = ToRegister(instr->result()); 2600 Register result = ToRegister(instr->result());
2601 2601
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 } 2829 }
2830 } 2830 }
2831 2831
2832 2832
2833 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2833 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2834 Register result = ToRegister(instr->result()); 2834 Register result = ToRegister(instr->result());
2835 2835
2836 Label done; 2836 Label done;
2837 2837
2838 // If no arguments adaptor frame the number of arguments is fixed. 2838 // If no arguments adaptor frame the number of arguments is fixed.
2839 if (instr->InputAt(0)->IsRegister()) { 2839 if (instr->elements()->IsRegister()) {
2840 __ cmpq(rbp, ToRegister(instr->InputAt(0))); 2840 __ cmpq(rbp, ToRegister(instr->elements()));
2841 } else { 2841 } else {
2842 __ cmpq(rbp, ToOperand(instr->InputAt(0))); 2842 __ cmpq(rbp, ToOperand(instr->elements()));
2843 } 2843 }
2844 __ movl(result, Immediate(scope()->num_parameters())); 2844 __ movl(result, Immediate(scope()->num_parameters()));
2845 __ j(equal, &done, Label::kNear); 2845 __ j(equal, &done, Label::kNear);
2846 2846
2847 // Arguments adaptor frame present. Get argument length from there. 2847 // Arguments adaptor frame present. Get argument length from there.
2848 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2848 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2849 __ SmiToInteger32(result, 2849 __ SmiToInteger32(result,
2850 Operand(result, 2850 Operand(result,
2851 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2851 ArgumentsAdaptorFrameConstants::kLengthOffset));
2852 2852
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2940 SafepointGenerator safepoint_generator( 2940 SafepointGenerator safepoint_generator(
2941 this, pointers, Safepoint::kLazyDeopt); 2941 this, pointers, Safepoint::kLazyDeopt);
2942 ParameterCount actual(rax); 2942 ParameterCount actual(rax);
2943 __ InvokeFunction(function, actual, CALL_FUNCTION, 2943 __ InvokeFunction(function, actual, CALL_FUNCTION,
2944 safepoint_generator, CALL_AS_METHOD); 2944 safepoint_generator, CALL_AS_METHOD);
2945 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2945 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2946 } 2946 }
2947 2947
2948 2948
2949 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2949 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2950 LOperand* argument = instr->InputAt(0); 2950 LOperand* argument = instr->value();
2951 EmitPushTaggedOperand(argument); 2951 EmitPushTaggedOperand(argument);
2952 } 2952 }
2953 2953
2954 2954
2955 void LCodeGen::DoDrop(LDrop* instr) { 2955 void LCodeGen::DoDrop(LDrop* instr) {
2956 __ Drop(instr->count()); 2956 __ Drop(instr->count());
2957 } 2957 }
2958 2958
2959 2959
2960 void LCodeGen::DoThisFunction(LThisFunction* instr) { 2960 void LCodeGen::DoThisFunction(LThisFunction* instr) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 ASSERT(ToRegister(instr->result()).is(rax)); 3050 ASSERT(ToRegister(instr->result()).is(rax));
3051 CallKnownFunction(instr->function(), 3051 CallKnownFunction(instr->function(),
3052 instr->arity(), 3052 instr->arity(),
3053 instr, 3053 instr,
3054 CALL_AS_METHOD, 3054 CALL_AS_METHOD,
3055 RDI_UNINITIALIZED); 3055 RDI_UNINITIALIZED);
3056 } 3056 }
3057 3057
3058 3058
3059 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3059 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
3060 Register input_reg = ToRegister(instr->InputAt(0)); 3060 Register input_reg = ToRegister(instr->value());
3061 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3061 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3062 Heap::kHeapNumberMapRootIndex); 3062 Heap::kHeapNumberMapRootIndex);
3063 DeoptimizeIf(not_equal, instr->environment()); 3063 DeoptimizeIf(not_equal, instr->environment());
3064 3064
3065 Label done; 3065 Label done;
3066 Register tmp = input_reg.is(rax) ? rcx : rax; 3066 Register tmp = input_reg.is(rax) ? rcx : rax;
3067 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 3067 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
3068 3068
3069 // Preserve the value of all registers. 3069 // Preserve the value of all registers.
3070 PushSafepointRegistersScope scope(this); 3070 PushSafepointRegistersScope scope(this);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 __ shl(tmp2, Immediate(1)); 3102 __ shl(tmp2, Immediate(1));
3103 __ shr(tmp2, Immediate(1)); 3103 __ shr(tmp2, Immediate(1));
3104 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 3104 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
3105 __ StoreToSafepointRegisterSlot(input_reg, tmp); 3105 __ StoreToSafepointRegisterSlot(input_reg, tmp);
3106 3106
3107 __ bind(&done); 3107 __ bind(&done);
3108 } 3108 }
3109 3109
3110 3110
3111 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3111 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3112 Register input_reg = ToRegister(instr->InputAt(0)); 3112 Register input_reg = ToRegister(instr->value());
3113 __ testl(input_reg, input_reg); 3113 __ testl(input_reg, input_reg);
3114 Label is_positive; 3114 Label is_positive;
3115 __ j(not_sign, &is_positive); 3115 __ j(not_sign, &is_positive);
3116 __ negl(input_reg); // Sets flags. 3116 __ negl(input_reg); // Sets flags.
3117 DeoptimizeIf(negative, instr->environment()); 3117 DeoptimizeIf(negative, instr->environment());
3118 __ bind(&is_positive); 3118 __ bind(&is_positive);
3119 } 3119 }
3120 3120
3121 3121
3122 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3122 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3123 // Class for deferred case. 3123 // Class for deferred case.
3124 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3124 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3125 public: 3125 public:
3126 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3126 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3127 LUnaryMathOperation* instr) 3127 LUnaryMathOperation* instr)
3128 : LDeferredCode(codegen), instr_(instr) { } 3128 : LDeferredCode(codegen), instr_(instr) { }
3129 virtual void Generate() { 3129 virtual void Generate() {
3130 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3130 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3131 } 3131 }
3132 virtual LInstruction* instr() { return instr_; } 3132 virtual LInstruction* instr() { return instr_; }
3133 private: 3133 private:
3134 LUnaryMathOperation* instr_; 3134 LUnaryMathOperation* instr_;
3135 }; 3135 };
3136 3136
3137 ASSERT(instr->InputAt(0)->Equals(instr->result())); 3137 ASSERT(instr->value()->Equals(instr->result()));
3138 Representation r = instr->hydrogen()->value()->representation(); 3138 Representation r = instr->hydrogen()->value()->representation();
3139 3139
3140 if (r.IsDouble()) { 3140 if (r.IsDouble()) {
3141 XMMRegister scratch = xmm0; 3141 XMMRegister scratch = xmm0;
3142 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 3142 XMMRegister input_reg = ToDoubleRegister(instr->value());
3143 __ xorps(scratch, scratch); 3143 __ xorps(scratch, scratch);
3144 __ subsd(scratch, input_reg); 3144 __ subsd(scratch, input_reg);
3145 __ andpd(input_reg, scratch); 3145 __ andpd(input_reg, scratch);
3146 } else if (r.IsInteger32()) { 3146 } else if (r.IsInteger32()) {
3147 EmitIntegerMathAbs(instr); 3147 EmitIntegerMathAbs(instr);
3148 } else { // Tagged case. 3148 } else { // Tagged case.
3149 DeferredMathAbsTaggedHeapNumber* deferred = 3149 DeferredMathAbsTaggedHeapNumber* deferred =
3150 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3150 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3151 Register input_reg = ToRegister(instr->InputAt(0)); 3151 Register input_reg = ToRegister(instr->value());
3152 // Smi check. 3152 // Smi check.
3153 __ JumpIfNotSmi(input_reg, deferred->entry()); 3153 __ JumpIfNotSmi(input_reg, deferred->entry());
3154 __ SmiToInteger32(input_reg, input_reg); 3154 __ SmiToInteger32(input_reg, input_reg);
3155 EmitIntegerMathAbs(instr); 3155 EmitIntegerMathAbs(instr);
3156 __ Integer32ToSmi(input_reg, input_reg); 3156 __ Integer32ToSmi(input_reg, input_reg);
3157 __ bind(deferred->exit()); 3157 __ bind(deferred->exit());
3158 } 3158 }
3159 } 3159 }
3160 3160
3161 3161
3162 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3162 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3163 XMMRegister xmm_scratch = xmm0; 3163 XMMRegister xmm_scratch = xmm0;
3164 Register output_reg = ToRegister(instr->result()); 3164 Register output_reg = ToRegister(instr->result());
3165 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 3165 XMMRegister input_reg = ToDoubleRegister(instr->value());
3166 3166
3167 if (CpuFeatures::IsSupported(SSE4_1)) { 3167 if (CpuFeatures::IsSupported(SSE4_1)) {
3168 CpuFeatures::Scope scope(SSE4_1); 3168 CpuFeatures::Scope scope(SSE4_1);
3169 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3169 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3170 // Deoptimize if minus zero. 3170 // Deoptimize if minus zero.
3171 __ movq(output_reg, input_reg); 3171 __ movq(output_reg, input_reg);
3172 __ subq(output_reg, Immediate(1)); 3172 __ subq(output_reg, Immediate(1));
3173 DeoptimizeIf(overflow, instr->environment()); 3173 DeoptimizeIf(overflow, instr->environment());
3174 } 3174 }
3175 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 3175 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3214 DeoptimizeIf(overflow, instr->environment()); 3214 DeoptimizeIf(overflow, instr->environment());
3215 3215
3216 __ bind(&done); 3216 __ bind(&done);
3217 } 3217 }
3218 } 3218 }
3219 3219
3220 3220
3221 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3221 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3222 const XMMRegister xmm_scratch = xmm0; 3222 const XMMRegister xmm_scratch = xmm0;
3223 Register output_reg = ToRegister(instr->result()); 3223 Register output_reg = ToRegister(instr->result());
3224 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 3224 XMMRegister input_reg = ToDoubleRegister(instr->value());
3225 3225
3226 Label done; 3226 Label done;
3227 // xmm_scratch = 0.5 3227 // xmm_scratch = 0.5
3228 __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE); 3228 __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE);
3229 __ movq(xmm_scratch, kScratchRegister); 3229 __ movq(xmm_scratch, kScratchRegister);
3230 Label below_half; 3230 Label below_half;
3231 __ ucomisd(xmm_scratch, input_reg); 3231 __ ucomisd(xmm_scratch, input_reg);
3232 // If input_reg is NaN, this doesn't jump. 3232 // If input_reg is NaN, this doesn't jump.
3233 __ j(above, &below_half, Label::kNear); 3233 __ j(above, &below_half, Label::kNear);
3234 // input = input + 0.5 3234 // input = input + 0.5
(...skipping 24 matching lines...) Expand all
3259 __ ucomisd(input_reg, xmm_scratch); 3259 __ ucomisd(input_reg, xmm_scratch);
3260 DeoptimizeIf(below, instr->environment()); 3260 DeoptimizeIf(below, instr->environment());
3261 } 3261 }
3262 __ xorl(output_reg, output_reg); 3262 __ xorl(output_reg, output_reg);
3263 3263
3264 __ bind(&done); 3264 __ bind(&done);
3265 } 3265 }
3266 3266
3267 3267
3268 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3268 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3269 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 3269 XMMRegister input_reg = ToDoubleRegister(instr->value());
3270 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3270 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3271 __ sqrtsd(input_reg, input_reg); 3271 __ sqrtsd(input_reg, input_reg);
3272 } 3272 }
3273 3273
3274 3274
3275 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3275 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3276 XMMRegister xmm_scratch = xmm0; 3276 XMMRegister xmm_scratch = xmm0;
3277 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 3277 XMMRegister input_reg = ToDoubleRegister(instr->value());
3278 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3278 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3279 3279
3280 // Note that according to ECMA-262 15.8.2.13: 3280 // Note that according to ECMA-262 15.8.2.13:
3281 // Math.pow(-Infinity, 0.5) == Infinity 3281 // Math.pow(-Infinity, 0.5) == Infinity
3282 // Math.sqrt(-Infinity) == NaN 3282 // Math.sqrt(-Infinity) == NaN
3283 Label done, sqrt; 3283 Label done, sqrt;
3284 // Check base for -Infinity. According to IEEE-754, double-precision 3284 // Check base for -Infinity. According to IEEE-754, double-precision
3285 // -Infinity has the highest 12 bits set and the lowest 52 bits cleared. 3285 // -Infinity has the highest 12 bits set and the lowest 52 bits cleared.
3286 __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000), RelocInfo::NONE); 3286 __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000), RelocInfo::NONE);
3287 __ movq(xmm_scratch, kScratchRegister); 3287 __ movq(xmm_scratch, kScratchRegister);
(...skipping 20 matching lines...) Expand all
3308 Representation exponent_type = instr->hydrogen()->right()->representation(); 3308 Representation exponent_type = instr->hydrogen()->right()->representation();
3309 // Having marked this as a call, we can use any registers. 3309 // Having marked this as a call, we can use any registers.
3310 // Just make sure that the input/output registers are the expected ones. 3310 // Just make sure that the input/output registers are the expected ones.
3311 3311
3312 // Choose register conforming to calling convention (when bailing out). 3312 // Choose register conforming to calling convention (when bailing out).
3313 #ifdef _WIN64 3313 #ifdef _WIN64
3314 Register exponent = rdx; 3314 Register exponent = rdx;
3315 #else 3315 #else
3316 Register exponent = rdi; 3316 Register exponent = rdi;
3317 #endif 3317 #endif
3318 ASSERT(!instr->InputAt(1)->IsRegister() || 3318 ASSERT(!instr->right()->IsRegister() ||
3319 ToRegister(instr->InputAt(1)).is(exponent)); 3319 ToRegister(instr->right()).is(exponent));
3320 ASSERT(!instr->InputAt(1)->IsDoubleRegister() || 3320 ASSERT(!instr->right()->IsDoubleRegister() ||
3321 ToDoubleRegister(instr->InputAt(1)).is(xmm1)); 3321 ToDoubleRegister(instr->right()).is(xmm1));
3322 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2)); 3322 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
3323 ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); 3323 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3324 3324
3325 if (exponent_type.IsTagged()) { 3325 if (exponent_type.IsTagged()) {
3326 Label no_deopt; 3326 Label no_deopt;
3327 __ JumpIfSmi(exponent, &no_deopt); 3327 __ JumpIfSmi(exponent, &no_deopt);
3328 __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx); 3328 __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx);
3329 DeoptimizeIf(not_equal, instr->environment()); 3329 DeoptimizeIf(not_equal, instr->environment());
3330 __ bind(&no_deopt); 3330 __ bind(&no_deopt);
3331 MathPowStub stub(MathPowStub::TAGGED); 3331 MathPowStub stub(MathPowStub::TAGGED);
3332 __ CallStub(&stub); 3332 __ CallStub(&stub);
(...skipping 21 matching lines...) Expand all
3354 3354
3355 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3355 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3356 3356
3357 // Having marked this instruction as a call we can use any 3357 // Having marked this instruction as a call we can use any
3358 // registers. 3358 // registers.
3359 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3359 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3360 3360
3361 // Choose the right register for the first argument depending on 3361 // Choose the right register for the first argument depending on
3362 // calling convention. 3362 // calling convention.
3363 #ifdef _WIN64 3363 #ifdef _WIN64
3364 ASSERT(ToRegister(instr->InputAt(0)).is(rcx)); 3364 ASSERT(ToRegister(instr->global_object()).is(rcx));
3365 Register global_object = rcx; 3365 Register global_object = rcx;
3366 #else 3366 #else
3367 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); 3367 ASSERT(ToRegister(instr->global_object()).is(rdi));
3368 Register global_object = rdi; 3368 Register global_object = rdi;
3369 #endif 3369 #endif
3370 3370
3371 static const int kSeedSize = sizeof(uint32_t); 3371 static const int kSeedSize = sizeof(uint32_t);
3372 STATIC_ASSERT(kPointerSize == 2 * kSeedSize); 3372 STATIC_ASSERT(kPointerSize == 2 * kSeedSize);
3373 3373
3374 __ movq(global_object, 3374 __ movq(global_object,
3375 FieldOperand(global_object, GlobalObject::kNativeContextOffset)); 3375 FieldOperand(global_object, GlobalObject::kNativeContextOffset));
3376 static const int kRandomSeedOffset = 3376 static const int kRandomSeedOffset =
3377 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3377 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
3572 ASSERT(ToRegister(instr->result()).is(rax)); 3572 ASSERT(ToRegister(instr->result()).is(rax));
3573 CallKnownFunction(instr->target(), 3573 CallKnownFunction(instr->target(),
3574 instr->arity(), 3574 instr->arity(),
3575 instr, 3575 instr,
3576 CALL_AS_FUNCTION, 3576 CALL_AS_FUNCTION,
3577 RDI_UNINITIALIZED); 3577 RDI_UNINITIALIZED);
3578 } 3578 }
3579 3579
3580 3580
3581 void LCodeGen::DoCallNew(LCallNew* instr) { 3581 void LCodeGen::DoCallNew(LCallNew* instr) {
3582 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); 3582 ASSERT(ToRegister(instr->constructor()).is(rdi));
3583 ASSERT(ToRegister(instr->result()).is(rax)); 3583 ASSERT(ToRegister(instr->result()).is(rax));
3584 3584
3585 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3585 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3586 __ Set(rax, instr->arity()); 3586 __ Set(rax, instr->arity());
3587 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 3587 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3588 } 3588 }
3589 3589
3590 3590
3591 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3591 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3592 CallRuntime(instr->function(), instr->arity(), instr); 3592 CallRuntime(instr->function(), instr->arity(), instr);
3593 } 3593 }
3594 3594
3595 3595
3596 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3596 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3597 Register object = ToRegister(instr->object()); 3597 Register object = ToRegister(instr->object());
3598 Register value = ToRegister(instr->value()); 3598 Register value = ToRegister(instr->value());
3599 int offset = instr->offset(); 3599 int offset = instr->offset();
3600 3600
3601 if (!instr->transition().is_null()) { 3601 if (!instr->transition().is_null()) {
3602 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 3602 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3603 __ Move(FieldOperand(object, HeapObject::kMapOffset), 3603 __ Move(FieldOperand(object, HeapObject::kMapOffset),
3604 instr->transition()); 3604 instr->transition());
3605 } else { 3605 } else {
3606 Register temp = ToRegister(instr->TempAt(0)); 3606 Register temp = ToRegister(instr->temp());
3607 __ Move(kScratchRegister, instr->transition()); 3607 __ Move(kScratchRegister, instr->transition());
3608 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 3608 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
3609 // Update the write barrier for the map field. 3609 // Update the write barrier for the map field.
3610 __ RecordWriteField(object, 3610 __ RecordWriteField(object,
3611 HeapObject::kMapOffset, 3611 HeapObject::kMapOffset,
3612 kScratchRegister, 3612 kScratchRegister,
3613 temp, 3613 temp,
3614 kSaveFPRegs, 3614 kSaveFPRegs,
3615 OMIT_REMEMBERED_SET, 3615 OMIT_REMEMBERED_SET,
3616 OMIT_SMI_CHECK); 3616 OMIT_SMI_CHECK);
3617 } 3617 }
3618 } 3618 }
3619 3619
3620 // Do the store. 3620 // Do the store.
3621 HType type = instr->hydrogen()->value()->type(); 3621 HType type = instr->hydrogen()->value()->type();
3622 SmiCheck check_needed = 3622 SmiCheck check_needed =
3623 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3623 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3624 if (instr->is_in_object()) { 3624 if (instr->is_in_object()) {
3625 __ movq(FieldOperand(object, offset), value); 3625 __ movq(FieldOperand(object, offset), value);
3626 if (instr->hydrogen()->NeedsWriteBarrier()) { 3626 if (instr->hydrogen()->NeedsWriteBarrier()) {
3627 Register temp = ToRegister(instr->TempAt(0)); 3627 Register temp = ToRegister(instr->temp());
3628 // Update the write barrier for the object for in-object properties. 3628 // Update the write barrier for the object for in-object properties.
3629 __ RecordWriteField(object, 3629 __ RecordWriteField(object,
3630 offset, 3630 offset,
3631 value, 3631 value,
3632 temp, 3632 temp,
3633 kSaveFPRegs, 3633 kSaveFPRegs,
3634 EMIT_REMEMBERED_SET, 3634 EMIT_REMEMBERED_SET,
3635 check_needed); 3635 check_needed);
3636 } 3636 }
3637 } else { 3637 } else {
3638 Register temp = ToRegister(instr->TempAt(0)); 3638 Register temp = ToRegister(instr->temp());
3639 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 3639 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
3640 __ movq(FieldOperand(temp, offset), value); 3640 __ movq(FieldOperand(temp, offset), value);
3641 if (instr->hydrogen()->NeedsWriteBarrier()) { 3641 if (instr->hydrogen()->NeedsWriteBarrier()) {
3642 // Update the write barrier for the properties array. 3642 // Update the write barrier for the properties array.
3643 // object is used as a scratch register. 3643 // object is used as a scratch register.
3644 __ RecordWriteField(temp, 3644 __ RecordWriteField(temp,
3645 offset, 3645 offset,
3646 value, 3646 value,
3647 object, 3647 object,
3648 kSaveFPRegs, 3648 kSaveFPRegs,
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3881 3881
3882 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3882 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3883 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3883 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3884 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3884 : isolate()->builtins()->KeyedStoreIC_Initialize();
3885 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3885 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3886 } 3886 }
3887 3887
3888 3888
3889 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3889 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3890 Register object_reg = ToRegister(instr->object()); 3890 Register object_reg = ToRegister(instr->object());
3891 Register new_map_reg = ToRegister(instr->new_map_reg()); 3891 Register new_map_reg = ToRegister(instr->new_map_temp());
3892 3892
3893 Handle<Map> from_map = instr->original_map(); 3893 Handle<Map> from_map = instr->original_map();
3894 Handle<Map> to_map = instr->transitioned_map(); 3894 Handle<Map> to_map = instr->transitioned_map();
3895 ElementsKind from_kind = from_map->elements_kind(); 3895 ElementsKind from_kind = from_map->elements_kind();
3896 ElementsKind to_kind = to_map->elements_kind(); 3896 ElementsKind to_kind = to_map->elements_kind();
3897 3897
3898 Label not_applicable; 3898 Label not_applicable;
3899 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3899 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3900 __ j(not_equal, &not_applicable); 3900 __ j(not_equal, &not_applicable);
3901 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); 3901 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
3902 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 3902 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
3903 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 3903 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3904 // Write barrier. 3904 // Write barrier.
3905 ASSERT_NE(instr->temp_reg(), NULL); 3905 ASSERT_NE(instr->temp(), NULL);
3906 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3906 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3907 ToRegister(instr->temp_reg()), kDontSaveFPRegs); 3907 ToRegister(instr->temp()), kDontSaveFPRegs);
3908 } else if (IsFastSmiElementsKind(from_kind) && 3908 } else if (IsFastSmiElementsKind(from_kind) &&
3909 IsFastDoubleElementsKind(to_kind)) { 3909 IsFastDoubleElementsKind(to_kind)) {
3910 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3910 Register fixed_object_reg = ToRegister(instr->temp());
3911 ASSERT(fixed_object_reg.is(rdx)); 3911 ASSERT(fixed_object_reg.is(rdx));
3912 ASSERT(new_map_reg.is(rbx)); 3912 ASSERT(new_map_reg.is(rbx));
3913 __ movq(fixed_object_reg, object_reg); 3913 __ movq(fixed_object_reg, object_reg);
3914 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3914 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3915 RelocInfo::CODE_TARGET, instr); 3915 RelocInfo::CODE_TARGET, instr);
3916 } else if (IsFastDoubleElementsKind(from_kind) && 3916 } else if (IsFastDoubleElementsKind(from_kind) &&
3917 IsFastObjectElementsKind(to_kind)) { 3917 IsFastObjectElementsKind(to_kind)) {
3918 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3918 Register fixed_object_reg = ToRegister(instr->temp());
3919 ASSERT(fixed_object_reg.is(rdx)); 3919 ASSERT(fixed_object_reg.is(rdx));
3920 ASSERT(new_map_reg.is(rbx)); 3920 ASSERT(new_map_reg.is(rbx));
3921 __ movq(fixed_object_reg, object_reg); 3921 __ movq(fixed_object_reg, object_reg);
3922 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3922 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3923 RelocInfo::CODE_TARGET, instr); 3923 RelocInfo::CODE_TARGET, instr);
3924 } else { 3924 } else {
3925 UNREACHABLE(); 3925 UNREACHABLE();
3926 } 3926 }
3927 __ bind(&not_applicable); 3927 __ bind(&not_applicable);
3928 } 3928 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 4039
4040 4040
4041 void LCodeGen::DoStringLength(LStringLength* instr) { 4041 void LCodeGen::DoStringLength(LStringLength* instr) {
4042 Register string = ToRegister(instr->string()); 4042 Register string = ToRegister(instr->string());
4043 Register result = ToRegister(instr->result()); 4043 Register result = ToRegister(instr->result());
4044 __ movq(result, FieldOperand(string, String::kLengthOffset)); 4044 __ movq(result, FieldOperand(string, String::kLengthOffset));
4045 } 4045 }
4046 4046
4047 4047
4048 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4048 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4049 LOperand* input = instr->InputAt(0); 4049 LOperand* input = instr->value();
4050 ASSERT(input->IsRegister() || input->IsStackSlot()); 4050 ASSERT(input->IsRegister() || input->IsStackSlot());
4051 LOperand* output = instr->result(); 4051 LOperand* output = instr->result();
4052 ASSERT(output->IsDoubleRegister()); 4052 ASSERT(output->IsDoubleRegister());
4053 if (input->IsRegister()) { 4053 if (input->IsRegister()) {
4054 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); 4054 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
4055 } else { 4055 } else {
4056 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); 4056 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
4057 } 4057 }
4058 } 4058 }
4059 4059
4060 4060
4061 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4061 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4062 LOperand* input = instr->InputAt(0); 4062 LOperand* input = instr->value();
4063 LOperand* output = instr->result(); 4063 LOperand* output = instr->result();
4064 LOperand* temp = instr->TempAt(0); 4064 LOperand* temp = instr->temp();
4065 4065
4066 __ LoadUint32(ToDoubleRegister(output), 4066 __ LoadUint32(ToDoubleRegister(output),
4067 ToRegister(input), 4067 ToRegister(input),
4068 ToDoubleRegister(temp)); 4068 ToDoubleRegister(temp));
4069 } 4069 }
4070 4070
4071 4071
4072 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4072 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4073 LOperand* input = instr->InputAt(0); 4073 LOperand* input = instr->value();
4074 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4074 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4075 Register reg = ToRegister(input); 4075 Register reg = ToRegister(input);
4076 4076
4077 __ Integer32ToSmi(reg, reg); 4077 __ Integer32ToSmi(reg, reg);
4078 } 4078 }
4079 4079
4080 4080
4081 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4081 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4082 class DeferredNumberTagU: public LDeferredCode { 4082 class DeferredNumberTagU: public LDeferredCode {
4083 public: 4083 public:
4084 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4084 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4085 : LDeferredCode(codegen), instr_(instr) { } 4085 : LDeferredCode(codegen), instr_(instr) { }
4086 virtual void Generate() { 4086 virtual void Generate() {
4087 codegen()->DoDeferredNumberTagU(instr_); 4087 codegen()->DoDeferredNumberTagU(instr_);
4088 } 4088 }
4089 virtual LInstruction* instr() { return instr_; } 4089 virtual LInstruction* instr() { return instr_; }
4090 private: 4090 private:
4091 LNumberTagU* instr_; 4091 LNumberTagU* instr_;
4092 }; 4092 };
4093 4093
4094 LOperand* input = instr->InputAt(0); 4094 LOperand* input = instr->value();
4095 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4095 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4096 Register reg = ToRegister(input); 4096 Register reg = ToRegister(input);
4097 4097
4098 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4098 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4099 __ cmpl(reg, Immediate(Smi::kMaxValue)); 4099 __ cmpl(reg, Immediate(Smi::kMaxValue));
4100 __ j(above, deferred->entry()); 4100 __ j(above, deferred->entry());
4101 __ Integer32ToSmi(reg, reg); 4101 __ Integer32ToSmi(reg, reg);
4102 __ bind(deferred->exit()); 4102 __ bind(deferred->exit());
4103 } 4103 }
4104 4104
4105 4105
4106 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) { 4106 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
4107 Label slow; 4107 Label slow;
4108 Register reg = ToRegister(instr->InputAt(0)); 4108 Register reg = ToRegister(instr->value());
4109 Register tmp = reg.is(rax) ? rcx : rax; 4109 Register tmp = reg.is(rax) ? rcx : rax;
4110 4110
4111 // Preserve the value of all registers. 4111 // Preserve the value of all registers.
4112 PushSafepointRegistersScope scope(this); 4112 PushSafepointRegistersScope scope(this);
4113 4113
4114 Label done; 4114 Label done;
4115 // Load value into xmm1 which will be preserved across potential call to 4115 // Load value into xmm1 which will be preserved across potential call to
4116 // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable 4116 // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable
4117 // XMM registers on x64). 4117 // XMM registers on x64).
4118 __ LoadUint32(xmm1, reg, xmm0); 4118 __ LoadUint32(xmm1, reg, xmm0);
(...skipping 26 matching lines...) Expand all
4145 class DeferredNumberTagD: public LDeferredCode { 4145 class DeferredNumberTagD: public LDeferredCode {
4146 public: 4146 public:
4147 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4147 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4148 : LDeferredCode(codegen), instr_(instr) { } 4148 : LDeferredCode(codegen), instr_(instr) { }
4149 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4149 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4150 virtual LInstruction* instr() { return instr_; } 4150 virtual LInstruction* instr() { return instr_; }
4151 private: 4151 private:
4152 LNumberTagD* instr_; 4152 LNumberTagD* instr_;
4153 }; 4153 };
4154 4154
4155 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 4155 XMMRegister input_reg = ToDoubleRegister(instr->value());
4156 Register reg = ToRegister(instr->result()); 4156 Register reg = ToRegister(instr->result());
4157 Register tmp = ToRegister(instr->TempAt(0)); 4157 Register tmp = ToRegister(instr->temp());
4158 4158
4159 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4159 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4160 if (FLAG_inline_new) { 4160 if (FLAG_inline_new) {
4161 __ AllocateHeapNumber(reg, tmp, deferred->entry()); 4161 __ AllocateHeapNumber(reg, tmp, deferred->entry());
4162 } else { 4162 } else {
4163 __ jmp(deferred->entry()); 4163 __ jmp(deferred->entry());
4164 } 4164 }
4165 __ bind(deferred->exit()); 4165 __ bind(deferred->exit());
4166 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4166 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4167 } 4167 }
(...skipping 10 matching lines...) Expand all
4178 PushSafepointRegistersScope scope(this); 4178 PushSafepointRegistersScope scope(this);
4179 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4179 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4180 // Ensure that value in rax survives popping registers. 4180 // Ensure that value in rax survives popping registers.
4181 __ movq(kScratchRegister, rax); 4181 __ movq(kScratchRegister, rax);
4182 } 4182 }
4183 __ movq(reg, kScratchRegister); 4183 __ movq(reg, kScratchRegister);
4184 } 4184 }
4185 4185
4186 4186
4187 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4187 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4188 ASSERT(instr->InputAt(0)->Equals(instr->result())); 4188 ASSERT(instr->value()->Equals(instr->result()));
4189 Register input = ToRegister(instr->InputAt(0)); 4189 Register input = ToRegister(instr->value());
4190 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4190 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4191 __ Integer32ToSmi(input, input); 4191 __ Integer32ToSmi(input, input);
4192 } 4192 }
4193 4193
4194 4194
4195 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4195 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4196 ASSERT(instr->InputAt(0)->Equals(instr->result())); 4196 ASSERT(instr->value()->Equals(instr->result()));
4197 Register input = ToRegister(instr->InputAt(0)); 4197 Register input = ToRegister(instr->value());
4198 if (instr->needs_check()) { 4198 if (instr->needs_check()) {
4199 Condition is_smi = __ CheckSmi(input); 4199 Condition is_smi = __ CheckSmi(input);
4200 DeoptimizeIf(NegateCondition(is_smi), instr->environment()); 4200 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4201 } else { 4201 } else {
4202 if (FLAG_debug_code) { 4202 if (FLAG_debug_code) {
4203 __ AbortIfNotSmi(input); 4203 __ AbortIfNotSmi(input);
4204 } 4204 }
4205 } 4205 }
4206 __ SmiToInteger32(input, input); 4206 __ SmiToInteger32(input, input);
4207 } 4207 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4252 // Smi to XMM conversion 4252 // Smi to XMM conversion
4253 __ bind(&load_smi); 4253 __ bind(&load_smi);
4254 __ SmiToInteger32(kScratchRegister, input_reg); 4254 __ SmiToInteger32(kScratchRegister, input_reg);
4255 __ cvtlsi2sd(result_reg, kScratchRegister); 4255 __ cvtlsi2sd(result_reg, kScratchRegister);
4256 __ bind(&done); 4256 __ bind(&done);
4257 } 4257 }
4258 4258
4259 4259
4260 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4260 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4261 Label done, heap_number; 4261 Label done, heap_number;
4262 Register input_reg = ToRegister(instr->InputAt(0)); 4262 Register input_reg = ToRegister(instr->value());
4263 4263
4264 // Heap number map check. 4264 // Heap number map check.
4265 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4265 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
4266 Heap::kHeapNumberMapRootIndex); 4266 Heap::kHeapNumberMapRootIndex);
4267 4267
4268 if (instr->truncating()) { 4268 if (instr->truncating()) {
4269 __ j(equal, &heap_number, Label::kNear); 4269 __ j(equal, &heap_number, Label::kNear);
4270 // Check for undefined. Undefined is converted to zero for truncating 4270 // Check for undefined. Undefined is converted to zero for truncating
4271 // conversions. 4271 // conversions.
4272 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 4272 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
4273 DeoptimizeIf(not_equal, instr->environment()); 4273 DeoptimizeIf(not_equal, instr->environment());
4274 __ Set(input_reg, 0); 4274 __ Set(input_reg, 0);
4275 __ jmp(&done, Label::kNear); 4275 __ jmp(&done, Label::kNear);
4276 4276
4277 __ bind(&heap_number); 4277 __ bind(&heap_number);
4278 4278
4279 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4279 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4280 __ cvttsd2siq(input_reg, xmm0); 4280 __ cvttsd2siq(input_reg, xmm0);
4281 __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); 4281 __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
4282 __ cmpq(input_reg, kScratchRegister); 4282 __ cmpq(input_reg, kScratchRegister);
4283 DeoptimizeIf(equal, instr->environment()); 4283 DeoptimizeIf(equal, instr->environment());
4284 } else { 4284 } else {
4285 // Deoptimize if we don't have a heap number. 4285 // Deoptimize if we don't have a heap number.
4286 DeoptimizeIf(not_equal, instr->environment()); 4286 DeoptimizeIf(not_equal, instr->environment());
4287 4287
4288 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); 4288 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4289 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4289 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4290 __ cvttsd2si(input_reg, xmm0); 4290 __ cvttsd2si(input_reg, xmm0);
4291 __ cvtlsi2sd(xmm_temp, input_reg); 4291 __ cvtlsi2sd(xmm_temp, input_reg);
4292 __ ucomisd(xmm0, xmm_temp); 4292 __ ucomisd(xmm0, xmm_temp);
4293 DeoptimizeIf(not_equal, instr->environment()); 4293 DeoptimizeIf(not_equal, instr->environment());
4294 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4294 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4295 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4295 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4296 __ testl(input_reg, input_reg); 4296 __ testl(input_reg, input_reg);
4297 __ j(not_zero, &done); 4297 __ j(not_zero, &done);
4298 __ movmskpd(input_reg, xmm0); 4298 __ movmskpd(input_reg, xmm0);
4299 __ andl(input_reg, Immediate(1)); 4299 __ andl(input_reg, Immediate(1));
4300 DeoptimizeIf(not_zero, instr->environment()); 4300 DeoptimizeIf(not_zero, instr->environment());
4301 } 4301 }
4302 } 4302 }
4303 __ bind(&done); 4303 __ bind(&done);
4304 } 4304 }
4305 4305
4306 4306
4307 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4307 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4308 class DeferredTaggedToI: public LDeferredCode { 4308 class DeferredTaggedToI: public LDeferredCode {
4309 public: 4309 public:
4310 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4310 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4311 : LDeferredCode(codegen), instr_(instr) { } 4311 : LDeferredCode(codegen), instr_(instr) { }
4312 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4312 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4313 virtual LInstruction* instr() { return instr_; } 4313 virtual LInstruction* instr() { return instr_; }
4314 private: 4314 private:
4315 LTaggedToI* instr_; 4315 LTaggedToI* instr_;
4316 }; 4316 };
4317 4317
4318 LOperand* input = instr->InputAt(0); 4318 LOperand* input = instr->value();
4319 ASSERT(input->IsRegister()); 4319 ASSERT(input->IsRegister());
4320 ASSERT(input->Equals(instr->result())); 4320 ASSERT(input->Equals(instr->result()));
4321 4321
4322 Register input_reg = ToRegister(input); 4322 Register input_reg = ToRegister(input);
4323 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4323 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4324 __ JumpIfNotSmi(input_reg, deferred->entry()); 4324 __ JumpIfNotSmi(input_reg, deferred->entry());
4325 __ SmiToInteger32(input_reg, input_reg); 4325 __ SmiToInteger32(input_reg, input_reg);
4326 __ bind(deferred->exit()); 4326 __ bind(deferred->exit());
4327 } 4327 }
4328 4328
4329 4329
4330 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4330 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4331 LOperand* input = instr->InputAt(0); 4331 LOperand* input = instr->value();
4332 ASSERT(input->IsRegister()); 4332 ASSERT(input->IsRegister());
4333 LOperand* result = instr->result(); 4333 LOperand* result = instr->result();
4334 ASSERT(result->IsDoubleRegister()); 4334 ASSERT(result->IsDoubleRegister());
4335 4335
4336 Register input_reg = ToRegister(input); 4336 Register input_reg = ToRegister(input);
4337 XMMRegister result_reg = ToDoubleRegister(result); 4337 XMMRegister result_reg = ToDoubleRegister(result);
4338 4338
4339 EmitNumberUntagD(input_reg, result_reg, 4339 EmitNumberUntagD(input_reg, result_reg,
4340 instr->hydrogen()->deoptimize_on_undefined(), 4340 instr->hydrogen()->deoptimize_on_undefined(),
4341 instr->hydrogen()->deoptimize_on_minus_zero(), 4341 instr->hydrogen()->deoptimize_on_minus_zero(),
4342 instr->environment()); 4342 instr->environment());
4343 } 4343 }
4344 4344
4345 4345
4346 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4346 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4347 LOperand* input = instr->InputAt(0); 4347 LOperand* input = instr->value();
4348 ASSERT(input->IsDoubleRegister()); 4348 ASSERT(input->IsDoubleRegister());
4349 LOperand* result = instr->result(); 4349 LOperand* result = instr->result();
4350 ASSERT(result->IsRegister()); 4350 ASSERT(result->IsRegister());
4351 4351
4352 XMMRegister input_reg = ToDoubleRegister(input); 4352 XMMRegister input_reg = ToDoubleRegister(input);
4353 Register result_reg = ToRegister(result); 4353 Register result_reg = ToRegister(result);
4354 4354
4355 if (instr->truncating()) { 4355 if (instr->truncating()) {
4356 // Performs a truncating conversion of a floating point number as used by 4356 // Performs a truncating conversion of a floating point number as used by
4357 // the JS bitwise operations. 4357 // the JS bitwise operations.
(...skipping 19 matching lines...) Expand all
4377 // deoptimize. 4377 // deoptimize.
4378 __ andl(result_reg, Immediate(1)); 4378 __ andl(result_reg, Immediate(1));
4379 DeoptimizeIf(not_zero, instr->environment()); 4379 DeoptimizeIf(not_zero, instr->environment());
4380 __ bind(&done); 4380 __ bind(&done);
4381 } 4381 }
4382 } 4382 }
4383 } 4383 }
4384 4384
4385 4385
4386 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4386 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4387 LOperand* input = instr->InputAt(0); 4387 LOperand* input = instr->value();
4388 Condition cc = masm()->CheckSmi(ToRegister(input)); 4388 Condition cc = masm()->CheckSmi(ToRegister(input));
4389 DeoptimizeIf(NegateCondition(cc), instr->environment()); 4389 DeoptimizeIf(NegateCondition(cc), instr->environment());
4390 } 4390 }
4391 4391
4392 4392
4393 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4393 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4394 LOperand* input = instr->InputAt(0); 4394 LOperand* input = instr->value();
4395 Condition cc = masm()->CheckSmi(ToRegister(input)); 4395 Condition cc = masm()->CheckSmi(ToRegister(input));
4396 DeoptimizeIf(cc, instr->environment()); 4396 DeoptimizeIf(cc, instr->environment());
4397 } 4397 }
4398 4398
4399 4399
4400 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4400 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4401 Register input = ToRegister(instr->InputAt(0)); 4401 Register input = ToRegister(instr->value());
4402 4402
4403 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); 4403 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset));
4404 4404
4405 if (instr->hydrogen()->is_interval_check()) { 4405 if (instr->hydrogen()->is_interval_check()) {
4406 InstanceType first; 4406 InstanceType first;
4407 InstanceType last; 4407 InstanceType last;
4408 instr->hydrogen()->GetCheckInterval(&first, &last); 4408 instr->hydrogen()->GetCheckInterval(&first, &last);
4409 4409
4410 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), 4410 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
4411 Immediate(static_cast<int8_t>(first))); 4411 Immediate(static_cast<int8_t>(first)));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4463 CompareMapMode mode, 4463 CompareMapMode mode,
4464 LEnvironment* env) { 4464 LEnvironment* env) {
4465 Label success; 4465 Label success;
4466 __ CompareMap(reg, map, &success, mode); 4466 __ CompareMap(reg, map, &success, mode);
4467 DeoptimizeIf(not_equal, env); 4467 DeoptimizeIf(not_equal, env);
4468 __ bind(&success); 4468 __ bind(&success);
4469 } 4469 }
4470 4470
4471 4471
4472 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4472 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4473 LOperand* input = instr->InputAt(0); 4473 LOperand* input = instr->value();
4474 ASSERT(input->IsRegister()); 4474 ASSERT(input->IsRegister());
4475 Register reg = ToRegister(input); 4475 Register reg = ToRegister(input);
4476 4476
4477 Label success; 4477 Label success;
4478 SmallMapList* map_set = instr->hydrogen()->map_set(); 4478 SmallMapList* map_set = instr->hydrogen()->map_set();
4479 for (int i = 0; i < map_set->length() - 1; i++) { 4479 for (int i = 0; i < map_set->length() - 1; i++) {
4480 Handle<Map> map = map_set->at(i); 4480 Handle<Map> map = map_set->at(i);
4481 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); 4481 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
4482 __ j(equal, &success); 4482 __ j(equal, &success);
4483 } 4483 }
4484 Handle<Map> map = map_set->last(); 4484 Handle<Map> map = map_set->last();
4485 DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment()); 4485 DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment());
4486 __ bind(&success); 4486 __ bind(&success);
4487 } 4487 }
4488 4488
4489 4489
4490 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4490 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4491 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 4491 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
4492 Register result_reg = ToRegister(instr->result()); 4492 Register result_reg = ToRegister(instr->result());
4493 Register temp_reg = ToRegister(instr->TempAt(0)); 4493 Register temp_reg = ToRegister(instr->temp());
4494 __ ClampDoubleToUint8(value_reg, xmm0, result_reg, temp_reg); 4494 __ ClampDoubleToUint8(value_reg, xmm0, result_reg, temp_reg);
4495 } 4495 }
4496 4496
4497 4497
4498 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4498 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
4499 ASSERT(instr->unclamped()->Equals(instr->result())); 4499 ASSERT(instr->unclamped()->Equals(instr->result()));
4500 Register value_reg = ToRegister(instr->result()); 4500 Register value_reg = ToRegister(instr->result());
4501 __ ClampUint8(value_reg); 4501 __ ClampUint8(value_reg);
4502 } 4502 }
4503 4503
4504 4504
4505 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4505 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
4506 ASSERT(instr->unclamped()->Equals(instr->result())); 4506 ASSERT(instr->unclamped()->Equals(instr->result()));
4507 Register input_reg = ToRegister(instr->unclamped()); 4507 Register input_reg = ToRegister(instr->unclamped());
4508 Register temp_reg = ToRegister(instr->TempAt(0)); 4508 Register temp_reg = ToRegister(instr->temp());
4509 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->TempAt(1)); 4509 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp2());
4510 Label is_smi, done, heap_number; 4510 Label is_smi, done, heap_number;
4511 4511
4512 __ JumpIfSmi(input_reg, &is_smi); 4512 __ JumpIfSmi(input_reg, &is_smi);
4513 4513
4514 // Check for heap number 4514 // Check for heap number
4515 __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 4515 __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
4516 factory()->heap_number_map()); 4516 factory()->heap_number_map());
4517 __ j(equal, &heap_number, Label::kNear); 4517 __ j(equal, &heap_number, Label::kNear);
4518 4518
4519 // Check for undefined. Undefined is converted to zero for clamping 4519 // Check for undefined. Undefined is converted to zero for clamping
(...skipping 12 matching lines...) Expand all
4532 // smi 4532 // smi
4533 __ bind(&is_smi); 4533 __ bind(&is_smi);
4534 __ SmiToInteger32(input_reg, input_reg); 4534 __ SmiToInteger32(input_reg, input_reg);
4535 __ ClampUint8(input_reg); 4535 __ ClampUint8(input_reg);
4536 4536
4537 __ bind(&done); 4537 __ bind(&done);
4538 } 4538 }
4539 4539
4540 4540
4541 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4541 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4542 Register reg = ToRegister(instr->TempAt(0)); 4542 Register reg = ToRegister(instr->temp());
4543 4543
4544 Handle<JSObject> holder = instr->holder(); 4544 Handle<JSObject> holder = instr->holder();
4545 Handle<JSObject> current_prototype = instr->prototype(); 4545 Handle<JSObject> current_prototype = instr->prototype();
4546 4546
4547 // Load prototype object. 4547 // Load prototype object.
4548 __ LoadHeapObject(reg, current_prototype); 4548 __ LoadHeapObject(reg, current_prototype);
4549 4549
4550 // Check prototype maps up to the holder. 4550 // Check prototype maps up to the holder.
4551 while (!current_prototype.is_identical_to(holder)) { 4551 while (!current_prototype.is_identical_to(holder)) {
4552 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()), 4552 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
(...skipping 18 matching lines...) Expand all
4571 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4571 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4572 virtual LInstruction* instr() { return instr_; } 4572 virtual LInstruction* instr() { return instr_; }
4573 private: 4573 private:
4574 LAllocateObject* instr_; 4574 LAllocateObject* instr_;
4575 }; 4575 };
4576 4576
4577 DeferredAllocateObject* deferred = 4577 DeferredAllocateObject* deferred =
4578 new(zone()) DeferredAllocateObject(this, instr); 4578 new(zone()) DeferredAllocateObject(this, instr);
4579 4579
4580 Register result = ToRegister(instr->result()); 4580 Register result = ToRegister(instr->result());
4581 Register scratch = ToRegister(instr->TempAt(0)); 4581 Register scratch = ToRegister(instr->temp());
4582 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4582 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4583 Handle<Map> initial_map(constructor->initial_map()); 4583 Handle<Map> initial_map(constructor->initial_map());
4584 int instance_size = initial_map->instance_size(); 4584 int instance_size = initial_map->instance_size();
4585 ASSERT(initial_map->pre_allocated_property_fields() + 4585 ASSERT(initial_map->pre_allocated_property_fields() +
4586 initial_map->unused_property_fields() - 4586 initial_map->unused_property_fields() -
4587 initial_map->inobject_properties() == 0); 4587 initial_map->inobject_properties() == 0);
4588 4588
4589 // Allocate memory for the object. The initial map might change when 4589 // Allocate memory for the object. The initial map might change when
4590 // the constructor's prototype changes, but instance size and property 4590 // the constructor's prototype changes, but instance size and property
4591 // counts remain unchanged (if slack tracking finished). 4591 // counts remain unchanged (if slack tracking finished).
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
4873 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 4873 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
4874 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 4874 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
4875 } else { 4875 } else {
4876 FastCloneShallowObjectStub stub(properties_count); 4876 FastCloneShallowObjectStub stub(properties_count);
4877 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4877 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4878 } 4878 }
4879 } 4879 }
4880 4880
4881 4881
4882 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 4882 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
4883 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); 4883 ASSERT(ToRegister(instr->value()).is(rax));
4884 __ push(rax); 4884 __ push(rax);
4885 CallRuntime(Runtime::kToFastProperties, 1, instr); 4885 CallRuntime(Runtime::kToFastProperties, 1, instr);
4886 } 4886 }
4887 4887
4888 4888
4889 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 4889 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
4890 Label materialized; 4890 Label materialized;
4891 // Registers will be used as follows: 4891 // Registers will be used as follows:
4892 // rcx = literals array. 4892 // rcx = literals array.
4893 // rbx = regexp literal. 4893 // rbx = regexp literal.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4950 __ Push(shared_info); 4950 __ Push(shared_info);
4951 __ PushRoot(pretenure ? 4951 __ PushRoot(pretenure ?
4952 Heap::kTrueValueRootIndex : 4952 Heap::kTrueValueRootIndex :
4953 Heap::kFalseValueRootIndex); 4953 Heap::kFalseValueRootIndex);
4954 CallRuntime(Runtime::kNewClosure, 3, instr); 4954 CallRuntime(Runtime::kNewClosure, 3, instr);
4955 } 4955 }
4956 } 4956 }
4957 4957
4958 4958
4959 void LCodeGen::DoTypeof(LTypeof* instr) { 4959 void LCodeGen::DoTypeof(LTypeof* instr) {
4960 LOperand* input = instr->InputAt(0); 4960 LOperand* input = instr->value();
4961 EmitPushTaggedOperand(input); 4961 EmitPushTaggedOperand(input);
4962 CallRuntime(Runtime::kTypeof, 1, instr); 4962 CallRuntime(Runtime::kTypeof, 1, instr);
4963 } 4963 }
4964 4964
4965 4965
4966 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 4966 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
4967 ASSERT(!operand->IsDoubleRegister()); 4967 ASSERT(!operand->IsDoubleRegister());
4968 if (operand->IsConstantOperand()) { 4968 if (operand->IsConstantOperand()) {
4969 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); 4969 Handle<Object> object = ToHandle(LConstantOperand::cast(operand));
4970 if (object->IsSmi()) { 4970 if (object->IsSmi()) {
4971 __ Push(Handle<Smi>::cast(object)); 4971 __ Push(Handle<Smi>::cast(object));
4972 } else { 4972 } else {
4973 __ PushHeapObject(Handle<HeapObject>::cast(object)); 4973 __ PushHeapObject(Handle<HeapObject>::cast(object));
4974 } 4974 }
4975 } else if (operand->IsRegister()) { 4975 } else if (operand->IsRegister()) {
4976 __ push(ToRegister(operand)); 4976 __ push(ToRegister(operand));
4977 } else { 4977 } else {
4978 __ push(ToOperand(operand)); 4978 __ push(ToOperand(operand));
4979 } 4979 }
4980 } 4980 }
4981 4981
4982 4982
4983 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 4983 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
4984 Register input = ToRegister(instr->InputAt(0)); 4984 Register input = ToRegister(instr->value());
4985 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4985 int true_block = chunk_->LookupDestination(instr->true_block_id());
4986 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4986 int false_block = chunk_->LookupDestination(instr->false_block_id());
4987 Label* true_label = chunk_->GetAssemblyLabel(true_block); 4987 Label* true_label = chunk_->GetAssemblyLabel(true_block);
4988 Label* false_label = chunk_->GetAssemblyLabel(false_block); 4988 Label* false_label = chunk_->GetAssemblyLabel(false_block);
4989 4989
4990 Condition final_branch_condition = 4990 Condition final_branch_condition =
4991 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); 4991 EmitTypeofIs(true_label, false_label, input, instr->type_literal());
4992 if (final_branch_condition != no_condition) { 4992 if (final_branch_condition != no_condition) {
4993 EmitBranch(true_block, false_block, final_branch_condition); 4993 EmitBranch(true_block, false_block, final_branch_condition);
4994 } 4994 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
5060 5060
5061 } else { 5061 } else {
5062 __ jmp(false_label); 5062 __ jmp(false_label);
5063 } 5063 }
5064 5064
5065 return final_branch_condition; 5065 return final_branch_condition;
5066 } 5066 }
5067 5067
5068 5068
5069 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5069 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5070 Register temp = ToRegister(instr->TempAt(0)); 5070 Register temp = ToRegister(instr->temp());
5071 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5071 int true_block = chunk_->LookupDestination(instr->true_block_id());
5072 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5072 int false_block = chunk_->LookupDestination(instr->false_block_id());
5073 5073
5074 EmitIsConstructCall(temp); 5074 EmitIsConstructCall(temp);
5075 EmitBranch(true_block, false_block, equal); 5075 EmitBranch(true_block, false_block, equal);
5076 } 5076 }
5077 5077
5078 5078
5079 void LCodeGen::EmitIsConstructCall(Register temp) { 5079 void LCodeGen::EmitIsConstructCall(Register temp) {
5080 // Get the frame pointer for the calling frame. 5080 // Get the frame pointer for the calling frame.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5313 FixedArray::kHeaderSize - kPointerSize)); 5313 FixedArray::kHeaderSize - kPointerSize));
5314 __ bind(&done); 5314 __ bind(&done);
5315 } 5315 }
5316 5316
5317 5317
5318 #undef __ 5318 #undef __
5319 5319
5320 } } // namespace v8::internal 5320 } } // namespace v8::internal
5321 5321
5322 #endif // V8_TARGET_ARCH_X64 5322 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698