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

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

Issue 6237002: Remove the remaining LOperand-members from concrete LIR instructions.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 } 739 }
740 } 740 }
741 741
742 742
743 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 743 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
744 // Nothing to do. 744 // Nothing to do.
745 } 745 }
746 746
747 747
748 void LCodeGen::DoModI(LModI* instr) { 748 void LCodeGen::DoModI(LModI* instr) {
749 LOperand* right = instr->right(); 749 LOperand* right = instr->InputAt(1);
750 ASSERT(ToRegister(instr->result()).is(edx)); 750 ASSERT(ToRegister(instr->result()).is(edx));
751 ASSERT(ToRegister(instr->left()).is(eax)); 751 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
752 ASSERT(!ToRegister(instr->right()).is(eax)); 752 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
753 ASSERT(!ToRegister(instr->right()).is(edx)); 753 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
754 754
755 Register right_reg = ToRegister(right); 755 Register right_reg = ToRegister(right);
756 756
757 // Check for x % 0. 757 // Check for x % 0.
758 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 758 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
759 __ test(right_reg, ToOperand(right)); 759 __ test(right_reg, ToOperand(right));
760 DeoptimizeIf(zero, instr->environment()); 760 DeoptimizeIf(zero, instr->environment());
761 } 761 }
762 762
763 // Sign extend to edx. 763 // Sign extend to edx.
(...skipping 15 matching lines...) Expand all
779 __ bind(&positive_left); 779 __ bind(&positive_left);
780 __ idiv(right_reg); 780 __ idiv(right_reg);
781 __ bind(&done); 781 __ bind(&done);
782 } else { 782 } else {
783 __ idiv(right_reg); 783 __ idiv(right_reg);
784 } 784 }
785 } 785 }
786 786
787 787
788 void LCodeGen::DoDivI(LDivI* instr) { 788 void LCodeGen::DoDivI(LDivI* instr) {
789 LOperand* right = instr->right(); 789 LOperand* right = instr->InputAt(1);
790 ASSERT(ToRegister(instr->result()).is(eax)); 790 ASSERT(ToRegister(instr->result()).is(eax));
791 ASSERT(ToRegister(instr->left()).is(eax)); 791 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
792 ASSERT(!ToRegister(instr->right()).is(eax)); 792 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
793 ASSERT(!ToRegister(instr->right()).is(edx)); 793 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
794 794
795 Register left_reg = eax; 795 Register left_reg = eax;
796 796
797 // Check for x / 0. 797 // Check for x / 0.
798 Register right_reg = ToRegister(right); 798 Register right_reg = ToRegister(right);
799 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 799 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
800 __ test(right_reg, ToOperand(right)); 800 __ test(right_reg, ToOperand(right));
801 DeoptimizeIf(zero, instr->environment()); 801 DeoptimizeIf(zero, instr->environment());
802 } 802 }
803 803
(...skipping 21 matching lines...) Expand all
825 __ cdq(); 825 __ cdq();
826 __ idiv(right_reg); 826 __ idiv(right_reg);
827 827
828 // Deoptimize if remainder is not 0. 828 // Deoptimize if remainder is not 0.
829 __ test(edx, Operand(edx)); 829 __ test(edx, Operand(edx));
830 DeoptimizeIf(not_zero, instr->environment()); 830 DeoptimizeIf(not_zero, instr->environment());
831 } 831 }
832 832
833 833
834 void LCodeGen::DoMulI(LMulI* instr) { 834 void LCodeGen::DoMulI(LMulI* instr) {
835 Register left = ToRegister(instr->left()); 835 Register left = ToRegister(instr->InputAt(0));
836 LOperand* right = instr->right(); 836 LOperand* right = instr->InputAt(1);
837 837
838 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 838 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
839 __ mov(ToRegister(instr->temp()), left); 839 __ mov(ToRegister(instr->TempAt(0)), left);
840 } 840 }
841 841
842 if (right->IsConstantOperand()) { 842 if (right->IsConstantOperand()) {
843 __ imul(left, left, ToInteger32(LConstantOperand::cast(right))); 843 __ imul(left, left, ToInteger32(LConstantOperand::cast(right)));
844 } else { 844 } else {
845 __ imul(left, ToOperand(right)); 845 __ imul(left, ToOperand(right));
846 } 846 }
847 847
848 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 848 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
849 DeoptimizeIf(overflow, instr->environment()); 849 DeoptimizeIf(overflow, instr->environment());
850 } 850 }
851 851
852 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 852 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
853 // Bail out if the result is supposed to be negative zero. 853 // Bail out if the result is supposed to be negative zero.
854 NearLabel done; 854 NearLabel done;
855 __ test(left, Operand(left)); 855 __ test(left, Operand(left));
856 __ j(not_zero, &done); 856 __ j(not_zero, &done);
857 if (right->IsConstantOperand()) { 857 if (right->IsConstantOperand()) {
858 if (ToInteger32(LConstantOperand::cast(right)) < 0) { 858 if (ToInteger32(LConstantOperand::cast(right)) < 0) {
859 DeoptimizeIf(no_condition, instr->environment()); 859 DeoptimizeIf(no_condition, instr->environment());
860 } 860 }
861 } else { 861 } else {
862 // Test the non-zero operand for negative sign. 862 // Test the non-zero operand for negative sign.
863 __ or_(ToRegister(instr->temp()), ToOperand(right)); 863 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
864 DeoptimizeIf(sign, instr->environment()); 864 DeoptimizeIf(sign, instr->environment());
865 } 865 }
866 __ bind(&done); 866 __ bind(&done);
867 } 867 }
868 } 868 }
869 869
870 870
871 void LCodeGen::DoBitI(LBitI* instr) { 871 void LCodeGen::DoBitI(LBitI* instr) {
872 LOperand* left = instr->left(); 872 LOperand* left = instr->InputAt(0);
873 LOperand* right = instr->right(); 873 LOperand* right = instr->InputAt(1);
874 ASSERT(left->Equals(instr->result())); 874 ASSERT(left->Equals(instr->result()));
875 ASSERT(left->IsRegister()); 875 ASSERT(left->IsRegister());
876 876
877 if (right->IsConstantOperand()) { 877 if (right->IsConstantOperand()) {
878 int right_operand = ToInteger32(LConstantOperand::cast(right)); 878 int right_operand = ToInteger32(LConstantOperand::cast(right));
879 switch (instr->op()) { 879 switch (instr->op()) {
880 case Token::BIT_AND: 880 case Token::BIT_AND:
881 __ and_(ToRegister(left), right_operand); 881 __ and_(ToRegister(left), right_operand);
882 break; 882 break;
883 case Token::BIT_OR: 883 case Token::BIT_OR:
(...skipping 19 matching lines...) Expand all
903 break; 903 break;
904 default: 904 default:
905 UNREACHABLE(); 905 UNREACHABLE();
906 break; 906 break;
907 } 907 }
908 } 908 }
909 } 909 }
910 910
911 911
912 void LCodeGen::DoShiftI(LShiftI* instr) { 912 void LCodeGen::DoShiftI(LShiftI* instr) {
913 LOperand* left = instr->left(); 913 LOperand* left = instr->InputAt(0);
914 LOperand* right = instr->right(); 914 LOperand* right = instr->InputAt(1);
915 ASSERT(left->Equals(instr->result())); 915 ASSERT(left->Equals(instr->result()));
916 ASSERT(left->IsRegister()); 916 ASSERT(left->IsRegister());
917 if (right->IsRegister()) { 917 if (right->IsRegister()) {
918 ASSERT(ToRegister(right).is(ecx)); 918 ASSERT(ToRegister(right).is(ecx));
919 919
920 switch (instr->op()) { 920 switch (instr->op()) {
921 case Token::SAR: 921 case Token::SAR:
922 __ sar_cl(ToRegister(left)); 922 __ sar_cl(ToRegister(left));
923 break; 923 break;
924 case Token::SHR: 924 case Token::SHR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 break; 959 break;
960 default: 960 default:
961 UNREACHABLE(); 961 UNREACHABLE();
962 break; 962 break;
963 } 963 }
964 } 964 }
965 } 965 }
966 966
967 967
968 void LCodeGen::DoSubI(LSubI* instr) { 968 void LCodeGen::DoSubI(LSubI* instr) {
969 LOperand* left = instr->left(); 969 LOperand* left = instr->InputAt(0);
970 LOperand* right = instr->right(); 970 LOperand* right = instr->InputAt(1);
971 ASSERT(left->Equals(instr->result())); 971 ASSERT(left->Equals(instr->result()));
972 972
973 if (right->IsConstantOperand()) { 973 if (right->IsConstantOperand()) {
974 __ sub(ToOperand(left), ToImmediate(right)); 974 __ sub(ToOperand(left), ToImmediate(right));
975 } else { 975 } else {
976 __ sub(ToRegister(left), ToOperand(right)); 976 __ sub(ToRegister(left), ToOperand(right));
977 } 977 }
978 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 978 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
979 DeoptimizeIf(overflow, instr->environment()); 979 DeoptimizeIf(overflow, instr->environment());
980 } 980 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 1015
1016 1016
1017 void LCodeGen::DoConstantT(LConstantT* instr) { 1017 void LCodeGen::DoConstantT(LConstantT* instr) {
1018 ASSERT(instr->result()->IsRegister()); 1018 ASSERT(instr->result()->IsRegister());
1019 __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1019 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1020 } 1020 }
1021 1021
1022 1022
1023 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1023 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1024 Register result = ToRegister(instr->result()); 1024 Register result = ToRegister(instr->result());
1025 Register array = ToRegister(instr->input()); 1025 Register array = ToRegister(instr->InputAt(0));
1026 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); 1026 __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
1027 } 1027 }
1028 1028
1029 1029
1030 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 1030 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
1031 Register result = ToRegister(instr->result()); 1031 Register result = ToRegister(instr->result());
1032 Register array = ToRegister(instr->input()); 1032 Register array = ToRegister(instr->InputAt(0));
1033 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); 1033 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
1034 } 1034 }
1035 1035
1036 1036
1037 void LCodeGen::DoValueOf(LValueOf* instr) { 1037 void LCodeGen::DoValueOf(LValueOf* instr) {
1038 Register input = ToRegister(instr->input()); 1038 Register input = ToRegister(instr->InputAt(0));
1039 Register result = ToRegister(instr->result()); 1039 Register result = ToRegister(instr->result());
1040 Register map = ToRegister(instr->temporary()); 1040 Register map = ToRegister(instr->TempAt(0));
1041 ASSERT(input.is(result)); 1041 ASSERT(input.is(result));
1042 NearLabel done; 1042 NearLabel done;
1043 // If the object is a smi return the object. 1043 // If the object is a smi return the object.
1044 __ test(input, Immediate(kSmiTagMask)); 1044 __ test(input, Immediate(kSmiTagMask));
1045 __ j(zero, &done); 1045 __ j(zero, &done);
1046 1046
1047 // If the object is not a value type, return the object. 1047 // If the object is not a value type, return the object.
1048 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1048 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1049 __ j(not_equal, &done); 1049 __ j(not_equal, &done);
1050 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1050 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1051 1051
1052 __ bind(&done); 1052 __ bind(&done);
1053 } 1053 }
1054 1054
1055 1055
1056 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1056 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1057 LOperand* input = instr->input(); 1057 LOperand* input = instr->InputAt(0);
1058 ASSERT(input->Equals(instr->result())); 1058 ASSERT(input->Equals(instr->result()));
1059 __ not_(ToRegister(input)); 1059 __ not_(ToRegister(input));
1060 } 1060 }
1061 1061
1062 1062
1063 void LCodeGen::DoThrow(LThrow* instr) { 1063 void LCodeGen::DoThrow(LThrow* instr) {
1064 __ push(ToOperand(instr->input())); 1064 __ push(ToOperand(instr->InputAt(0)));
1065 CallRuntime(Runtime::kThrow, 1, instr); 1065 CallRuntime(Runtime::kThrow, 1, instr);
1066 1066
1067 if (FLAG_debug_code) { 1067 if (FLAG_debug_code) {
1068 Comment("Unreachable code."); 1068 Comment("Unreachable code.");
1069 __ int3(); 1069 __ int3();
1070 } 1070 }
1071 } 1071 }
1072 1072
1073 1073
1074 void LCodeGen::DoAddI(LAddI* instr) { 1074 void LCodeGen::DoAddI(LAddI* instr) {
1075 LOperand* left = instr->left(); 1075 LOperand* left = instr->InputAt(0);
1076 LOperand* right = instr->right(); 1076 LOperand* right = instr->InputAt(1);
1077 ASSERT(left->Equals(instr->result())); 1077 ASSERT(left->Equals(instr->result()));
1078 1078
1079 if (right->IsConstantOperand()) { 1079 if (right->IsConstantOperand()) {
1080 __ add(ToOperand(left), ToImmediate(right)); 1080 __ add(ToOperand(left), ToImmediate(right));
1081 } else { 1081 } else {
1082 __ add(ToRegister(left), ToOperand(right)); 1082 __ add(ToRegister(left), ToOperand(right));
1083 } 1083 }
1084 1084
1085 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1085 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1086 DeoptimizeIf(overflow, instr->environment()); 1086 DeoptimizeIf(overflow, instr->environment());
1087 } 1087 }
1088 } 1088 }
1089 1089
1090 1090
1091 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1091 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1092 LOperand* left = instr->left(); 1092 LOperand* left = instr->InputAt(0);
1093 LOperand* right = instr->right(); 1093 LOperand* right = instr->InputAt(1);
1094 // Modulo uses a fixed result register. 1094 // Modulo uses a fixed result register.
1095 ASSERT(instr->op() == Token::MOD || left->Equals(instr->result())); 1095 ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
1096 switch (instr->op()) { 1096 switch (instr->op()) {
1097 case Token::ADD: 1097 case Token::ADD:
1098 __ addsd(ToDoubleRegister(left), ToDoubleRegister(right)); 1098 __ addsd(ToDoubleRegister(left), ToDoubleRegister(right));
1099 break; 1099 break;
1100 case Token::SUB: 1100 case Token::SUB:
1101 __ subsd(ToDoubleRegister(left), ToDoubleRegister(right)); 1101 __ subsd(ToDoubleRegister(left), ToDoubleRegister(right));
1102 break; 1102 break;
1103 case Token::MUL: 1103 case Token::MUL:
(...skipping 18 matching lines...) Expand all
1122 break; 1122 break;
1123 } 1123 }
1124 default: 1124 default:
1125 UNREACHABLE(); 1125 UNREACHABLE();
1126 break; 1126 break;
1127 } 1127 }
1128 } 1128 }
1129 1129
1130 1130
1131 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1131 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1132 ASSERT(ToRegister(instr->left()).is(edx)); 1132 ASSERT(ToRegister(instr->InputAt(0)).is(edx));
1133 ASSERT(ToRegister(instr->right()).is(eax)); 1133 ASSERT(ToRegister(instr->InputAt(1)).is(eax));
1134 ASSERT(ToRegister(instr->result()).is(eax)); 1134 ASSERT(ToRegister(instr->result()).is(eax));
1135 1135
1136 TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE); 1136 TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
1137 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1137 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1138 } 1138 }
1139 1139
1140 1140
1141 int LCodeGen::GetNextEmittedBlock(int block) { 1141 int LCodeGen::GetNextEmittedBlock(int block) {
1142 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1142 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
1143 LLabel* label = chunk_->GetLabel(i); 1143 LLabel* label = chunk_->GetLabel(i);
(...skipping 20 matching lines...) Expand all
1164 } 1164 }
1165 } 1165 }
1166 1166
1167 1167
1168 void LCodeGen::DoBranch(LBranch* instr) { 1168 void LCodeGen::DoBranch(LBranch* instr) {
1169 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1169 int true_block = chunk_->LookupDestination(instr->true_block_id());
1170 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1170 int false_block = chunk_->LookupDestination(instr->false_block_id());
1171 1171
1172 Representation r = instr->hydrogen()->representation(); 1172 Representation r = instr->hydrogen()->representation();
1173 if (r.IsInteger32()) { 1173 if (r.IsInteger32()) {
1174 Register reg = ToRegister(instr->input()); 1174 Register reg = ToRegister(instr->InputAt(0));
1175 __ test(reg, Operand(reg)); 1175 __ test(reg, Operand(reg));
1176 EmitBranch(true_block, false_block, not_zero); 1176 EmitBranch(true_block, false_block, not_zero);
1177 } else if (r.IsDouble()) { 1177 } else if (r.IsDouble()) {
1178 XMMRegister reg = ToDoubleRegister(instr->input()); 1178 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1179 __ xorpd(xmm0, xmm0); 1179 __ xorpd(xmm0, xmm0);
1180 __ ucomisd(reg, xmm0); 1180 __ ucomisd(reg, xmm0);
1181 EmitBranch(true_block, false_block, not_equal); 1181 EmitBranch(true_block, false_block, not_equal);
1182 } else { 1182 } else {
1183 ASSERT(r.IsTagged()); 1183 ASSERT(r.IsTagged());
1184 Register reg = ToRegister(instr->input()); 1184 Register reg = ToRegister(instr->InputAt(0));
1185 if (instr->hydrogen()->type().IsBoolean()) { 1185 if (instr->hydrogen()->type().IsBoolean()) {
1186 __ cmp(reg, Factory::true_value()); 1186 __ cmp(reg, Factory::true_value());
1187 EmitBranch(true_block, false_block, equal); 1187 EmitBranch(true_block, false_block, equal);
1188 } else { 1188 } else {
1189 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1189 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1190 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1190 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1191 1191
1192 __ cmp(reg, Factory::undefined_value()); 1192 __ cmp(reg, Factory::undefined_value());
1193 __ j(equal, false_label); 1193 __ j(equal, false_label);
1194 __ cmp(reg, Factory::true_value()); 1194 __ cmp(reg, Factory::true_value());
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { 1302 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
1303 if (right->IsConstantOperand()) { 1303 if (right->IsConstantOperand()) {
1304 __ cmp(ToOperand(left), ToImmediate(right)); 1304 __ cmp(ToOperand(left), ToImmediate(right));
1305 } else { 1305 } else {
1306 __ cmp(ToRegister(left), ToOperand(right)); 1306 __ cmp(ToRegister(left), ToOperand(right));
1307 } 1307 }
1308 } 1308 }
1309 1309
1310 1310
1311 void LCodeGen::DoCmpID(LCmpID* instr) { 1311 void LCodeGen::DoCmpID(LCmpID* instr) {
1312 LOperand* left = instr->left(); 1312 LOperand* left = instr->InputAt(0);
1313 LOperand* right = instr->right(); 1313 LOperand* right = instr->InputAt(1);
1314 LOperand* result = instr->result(); 1314 LOperand* result = instr->result();
1315 1315
1316 NearLabel unordered; 1316 NearLabel unordered;
1317 if (instr->is_double()) { 1317 if (instr->is_double()) {
1318 // Don't base result on EFLAGS when a NaN is involved. Instead 1318 // Don't base result on EFLAGS when a NaN is involved. Instead
1319 // jump to the unordered case, which produces a false value. 1319 // jump to the unordered case, which produces a false value.
1320 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1320 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1321 __ j(parity_even, &unordered, not_taken); 1321 __ j(parity_even, &unordered, not_taken);
1322 } else { 1322 } else {
1323 EmitCmpI(left, right); 1323 EmitCmpI(left, right);
1324 } 1324 }
1325 1325
1326 NearLabel done; 1326 NearLabel done;
1327 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1327 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1328 __ mov(ToRegister(result), Handle<Object>(Heap::true_value())); 1328 __ mov(ToRegister(result), Handle<Object>(Heap::true_value()));
1329 __ j(cc, &done); 1329 __ j(cc, &done);
1330 1330
1331 __ bind(&unordered); 1331 __ bind(&unordered);
1332 __ mov(ToRegister(result), Handle<Object>(Heap::false_value())); 1332 __ mov(ToRegister(result), Handle<Object>(Heap::false_value()));
1333 __ bind(&done); 1333 __ bind(&done);
1334 } 1334 }
1335 1335
1336 1336
1337 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1337 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1338 LOperand* left = instr->left(); 1338 LOperand* left = instr->InputAt(0);
1339 LOperand* right = instr->right(); 1339 LOperand* right = instr->InputAt(1);
1340 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1340 int false_block = chunk_->LookupDestination(instr->false_block_id());
1341 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1341 int true_block = chunk_->LookupDestination(instr->true_block_id());
1342 1342
1343 if (instr->is_double()) { 1343 if (instr->is_double()) {
1344 // Don't base result on EFLAGS when a NaN is involved. Instead 1344 // Don't base result on EFLAGS when a NaN is involved. Instead
1345 // jump to the false block. 1345 // jump to the false block.
1346 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1346 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1347 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 1347 __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
1348 } else { 1348 } else {
1349 EmitCmpI(left, right); 1349 EmitCmpI(left, right);
1350 } 1350 }
1351 1351
1352 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1352 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1353 EmitBranch(true_block, false_block, cc); 1353 EmitBranch(true_block, false_block, cc);
1354 } 1354 }
1355 1355
1356 1356
1357 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { 1357 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
1358 Register left = ToRegister(instr->left()); 1358 Register left = ToRegister(instr->InputAt(0));
1359 Register right = ToRegister(instr->right()); 1359 Register right = ToRegister(instr->InputAt(1));
1360 Register result = ToRegister(instr->result()); 1360 Register result = ToRegister(instr->result());
1361 1361
1362 __ cmp(left, Operand(right)); 1362 __ cmp(left, Operand(right));
1363 __ mov(result, Handle<Object>(Heap::true_value())); 1363 __ mov(result, Handle<Object>(Heap::true_value()));
1364 NearLabel done; 1364 NearLabel done;
1365 __ j(equal, &done); 1365 __ j(equal, &done);
1366 __ mov(result, Handle<Object>(Heap::false_value())); 1366 __ mov(result, Handle<Object>(Heap::false_value()));
1367 __ bind(&done); 1367 __ bind(&done);
1368 } 1368 }
1369 1369
1370 1370
1371 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { 1371 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
1372 Register left = ToRegister(instr->left()); 1372 Register left = ToRegister(instr->InputAt(0));
1373 Register right = ToRegister(instr->right()); 1373 Register right = ToRegister(instr->InputAt(1));
1374 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1374 int false_block = chunk_->LookupDestination(instr->false_block_id());
1375 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1375 int true_block = chunk_->LookupDestination(instr->true_block_id());
1376 1376
1377 __ cmp(left, Operand(right)); 1377 __ cmp(left, Operand(right));
1378 EmitBranch(true_block, false_block, equal); 1378 EmitBranch(true_block, false_block, equal);
1379 } 1379 }
1380 1380
1381 1381
1382 void LCodeGen::DoIsNull(LIsNull* instr) { 1382 void LCodeGen::DoIsNull(LIsNull* instr) {
1383 Register reg = ToRegister(instr->input()); 1383 Register reg = ToRegister(instr->InputAt(0));
1384 Register result = ToRegister(instr->result()); 1384 Register result = ToRegister(instr->result());
1385 1385
1386 // TODO(fsc): If the expression is known to be a smi, then it's 1386 // TODO(fsc): If the expression is known to be a smi, then it's
1387 // definitely not null. Materialize false. 1387 // definitely not null. Materialize false.
1388 1388
1389 __ cmp(reg, Factory::null_value()); 1389 __ cmp(reg, Factory::null_value());
1390 if (instr->is_strict()) { 1390 if (instr->is_strict()) {
1391 __ mov(result, Handle<Object>(Heap::true_value())); 1391 __ mov(result, Handle<Object>(Heap::true_value()));
1392 NearLabel done; 1392 NearLabel done;
1393 __ j(equal, &done); 1393 __ j(equal, &done);
(...skipping 17 matching lines...) Expand all
1411 __ mov(result, Handle<Object>(Heap::false_value())); 1411 __ mov(result, Handle<Object>(Heap::false_value()));
1412 __ jmp(&done); 1412 __ jmp(&done);
1413 __ bind(&true_value); 1413 __ bind(&true_value);
1414 __ mov(result, Handle<Object>(Heap::true_value())); 1414 __ mov(result, Handle<Object>(Heap::true_value()));
1415 __ bind(&done); 1415 __ bind(&done);
1416 } 1416 }
1417 } 1417 }
1418 1418
1419 1419
1420 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1420 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1421 Register reg = ToRegister(instr->input()); 1421 Register reg = ToRegister(instr->InputAt(0));
1422 1422
1423 // TODO(fsc): If the expression is known to be a smi, then it's 1423 // TODO(fsc): If the expression is known to be a smi, then it's
1424 // definitely not null. Jump to the false block. 1424 // definitely not null. Jump to the false block.
1425 1425
1426 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1426 int true_block = chunk_->LookupDestination(instr->true_block_id());
1427 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1427 int false_block = chunk_->LookupDestination(instr->false_block_id());
1428 1428
1429 __ cmp(reg, Factory::null_value()); 1429 __ cmp(reg, Factory::null_value());
1430 if (instr->is_strict()) { 1430 if (instr->is_strict()) {
1431 EmitBranch(true_block, false_block, equal); 1431 EmitBranch(true_block, false_block, equal);
1432 } else { 1432 } else {
1433 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1433 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1434 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1434 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1435 __ j(equal, true_label); 1435 __ j(equal, true_label);
1436 __ cmp(reg, Factory::undefined_value()); 1436 __ cmp(reg, Factory::undefined_value());
1437 __ j(equal, true_label); 1437 __ j(equal, true_label);
1438 __ test(reg, Immediate(kSmiTagMask)); 1438 __ test(reg, Immediate(kSmiTagMask));
1439 __ j(zero, false_label); 1439 __ j(zero, false_label);
1440 // Check for undetectable objects by looking in the bit field in 1440 // Check for undetectable objects by looking in the bit field in
1441 // the map. The object has already been smi checked. 1441 // the map. The object has already been smi checked.
1442 Register scratch = ToRegister(instr->temp()); 1442 Register scratch = ToRegister(instr->TempAt(0));
1443 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1443 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1444 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1444 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1445 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1445 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1446 EmitBranch(true_block, false_block, not_zero); 1446 EmitBranch(true_block, false_block, not_zero);
1447 } 1447 }
1448 } 1448 }
1449 1449
1450 1450
1451 Condition LCodeGen::EmitIsObject(Register input, 1451 Condition LCodeGen::EmitIsObject(Register input,
1452 Register temp1, 1452 Register temp1,
(...skipping 18 matching lines...) Expand all
1471 1471
1472 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset)); 1472 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
1473 __ cmp(temp2, FIRST_JS_OBJECT_TYPE); 1473 __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
1474 __ j(below, is_not_object); 1474 __ j(below, is_not_object);
1475 __ cmp(temp2, LAST_JS_OBJECT_TYPE); 1475 __ cmp(temp2, LAST_JS_OBJECT_TYPE);
1476 return below_equal; 1476 return below_equal;
1477 } 1477 }
1478 1478
1479 1479
1480 void LCodeGen::DoIsObject(LIsObject* instr) { 1480 void LCodeGen::DoIsObject(LIsObject* instr) {
1481 Register reg = ToRegister(instr->input()); 1481 Register reg = ToRegister(instr->InputAt(0));
1482 Register result = ToRegister(instr->result()); 1482 Register result = ToRegister(instr->result());
1483 Register temp = ToRegister(instr->temp()); 1483 Register temp = ToRegister(instr->TempAt(0));
1484 Label is_false, is_true, done; 1484 Label is_false, is_true, done;
1485 1485
1486 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); 1486 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
1487 __ j(true_cond, &is_true); 1487 __ j(true_cond, &is_true);
1488 1488
1489 __ bind(&is_false); 1489 __ bind(&is_false);
1490 __ mov(result, Handle<Object>(Heap::false_value())); 1490 __ mov(result, Handle<Object>(Heap::false_value()));
1491 __ jmp(&done); 1491 __ jmp(&done);
1492 1492
1493 __ bind(&is_true); 1493 __ bind(&is_true);
1494 __ mov(result, Handle<Object>(Heap::true_value())); 1494 __ mov(result, Handle<Object>(Heap::true_value()));
1495 1495
1496 __ bind(&done); 1496 __ bind(&done);
1497 } 1497 }
1498 1498
1499 1499
1500 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1500 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1501 Register reg = ToRegister(instr->input()); 1501 Register reg = ToRegister(instr->InputAt(0));
1502 Register temp = ToRegister(instr->temp()); 1502 Register temp = ToRegister(instr->TempAt(0));
1503 Register temp2 = ToRegister(instr->temp2()); 1503 Register temp2 = ToRegister(instr->TempAt(1));
1504 1504
1505 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1505 int true_block = chunk_->LookupDestination(instr->true_block_id());
1506 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1506 int false_block = chunk_->LookupDestination(instr->false_block_id());
1507 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1507 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1508 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1508 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1509 1509
1510 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); 1510 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label);
1511 1511
1512 EmitBranch(true_block, false_block, true_cond); 1512 EmitBranch(true_block, false_block, true_cond);
1513 } 1513 }
1514 1514
1515 1515
1516 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1516 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1517 Operand input = ToOperand(instr->input()); 1517 Operand input = ToOperand(instr->InputAt(0));
1518 Register result = ToRegister(instr->result()); 1518 Register result = ToRegister(instr->result());
1519 1519
1520 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1520 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1521 __ test(input, Immediate(kSmiTagMask)); 1521 __ test(input, Immediate(kSmiTagMask));
1522 __ mov(result, Handle<Object>(Heap::true_value())); 1522 __ mov(result, Handle<Object>(Heap::true_value()));
1523 NearLabel done; 1523 NearLabel done;
1524 __ j(zero, &done); 1524 __ j(zero, &done);
1525 __ mov(result, Handle<Object>(Heap::false_value())); 1525 __ mov(result, Handle<Object>(Heap::false_value()));
1526 __ bind(&done); 1526 __ bind(&done);
1527 } 1527 }
1528 1528
1529 1529
1530 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1530 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1531 Operand input = ToOperand(instr->input()); 1531 Operand input = ToOperand(instr->InputAt(0));
1532 1532
1533 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1533 int true_block = chunk_->LookupDestination(instr->true_block_id());
1534 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1534 int false_block = chunk_->LookupDestination(instr->false_block_id());
1535 1535
1536 __ test(input, Immediate(kSmiTagMask)); 1536 __ test(input, Immediate(kSmiTagMask));
1537 EmitBranch(true_block, false_block, zero); 1537 EmitBranch(true_block, false_block, zero);
1538 } 1538 }
1539 1539
1540 1540
1541 InstanceType LHasInstanceType::TestType() { 1541 static InstanceType TestType(HHasInstanceType* instr) {
1542 InstanceType from = hydrogen()->from(); 1542 InstanceType from = instr->from();
1543 InstanceType to = hydrogen()->to(); 1543 InstanceType to = instr->to();
1544 if (from == FIRST_TYPE) return to; 1544 if (from == FIRST_TYPE) return to;
1545 ASSERT(from == to || to == LAST_TYPE); 1545 ASSERT(from == to || to == LAST_TYPE);
1546 return from; 1546 return from;
1547 } 1547 }
1548 1548
1549 1549
1550 1550
1551 Condition LHasInstanceType::BranchCondition() { 1551 static Condition BranchCondition(HHasInstanceType* instr) {
1552 InstanceType from = hydrogen()->from(); 1552 InstanceType from = instr->from();
1553 InstanceType to = hydrogen()->to(); 1553 InstanceType to = instr->to();
1554 if (from == to) return equal; 1554 if (from == to) return equal;
1555 if (to == LAST_TYPE) return above_equal; 1555 if (to == LAST_TYPE) return above_equal;
1556 if (from == FIRST_TYPE) return below_equal; 1556 if (from == FIRST_TYPE) return below_equal;
1557 UNREACHABLE(); 1557 UNREACHABLE();
1558 return equal; 1558 return equal;
1559 } 1559 }
1560 1560
1561 1561
1562 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { 1562 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1563 Register input = ToRegister(instr->input()); 1563 Register input = ToRegister(instr->InputAt(0));
1564 Register result = ToRegister(instr->result()); 1564 Register result = ToRegister(instr->result());
1565 1565
1566 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1566 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1567 __ test(input, Immediate(kSmiTagMask)); 1567 __ test(input, Immediate(kSmiTagMask));
1568 NearLabel done, is_false; 1568 NearLabel done, is_false;
1569 __ j(zero, &is_false); 1569 __ j(zero, &is_false);
1570 __ CmpObjectType(input, instr->TestType(), result); 1570 __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1571 __ j(NegateCondition(instr->BranchCondition()), &is_false); 1571 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
1572 __ mov(result, Handle<Object>(Heap::true_value())); 1572 __ mov(result, Handle<Object>(Heap::true_value()));
1573 __ jmp(&done); 1573 __ jmp(&done);
1574 __ bind(&is_false); 1574 __ bind(&is_false);
1575 __ mov(result, Handle<Object>(Heap::false_value())); 1575 __ mov(result, Handle<Object>(Heap::false_value()));
1576 __ bind(&done); 1576 __ bind(&done);
1577 } 1577 }
1578 1578
1579 1579
1580 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1580 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1581 Register input = ToRegister(instr->input()); 1581 Register input = ToRegister(instr->InputAt(0));
1582 Register temp = ToRegister(instr->temp()); 1582 Register temp = ToRegister(instr->TempAt(0));
1583 1583
1584 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1584 int true_block = chunk_->LookupDestination(instr->true_block_id());
1585 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1585 int false_block = chunk_->LookupDestination(instr->false_block_id());
1586 1586
1587 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1587 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1588 1588
1589 __ test(input, Immediate(kSmiTagMask)); 1589 __ test(input, Immediate(kSmiTagMask));
1590 __ j(zero, false_label); 1590 __ j(zero, false_label);
1591 1591
1592 __ CmpObjectType(input, instr->TestType(), temp); 1592 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
1593 EmitBranch(true_block, false_block, instr->BranchCondition()); 1593 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1594 } 1594 }
1595 1595
1596 1596
1597 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { 1597 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1598 Register input = ToRegister(instr->input()); 1598 Register input = ToRegister(instr->InputAt(0));
1599 Register result = ToRegister(instr->result()); 1599 Register result = ToRegister(instr->result());
1600 1600
1601 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1601 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1602 __ mov(result, Handle<Object>(Heap::true_value())); 1602 __ mov(result, Handle<Object>(Heap::true_value()));
1603 __ test(FieldOperand(input, String::kHashFieldOffset), 1603 __ test(FieldOperand(input, String::kHashFieldOffset),
1604 Immediate(String::kContainsCachedArrayIndexMask)); 1604 Immediate(String::kContainsCachedArrayIndexMask));
1605 NearLabel done; 1605 NearLabel done;
1606 __ j(not_zero, &done); 1606 __ j(not_zero, &done);
1607 __ mov(result, Handle<Object>(Heap::false_value())); 1607 __ mov(result, Handle<Object>(Heap::false_value()));
1608 __ bind(&done); 1608 __ bind(&done);
1609 } 1609 }
1610 1610
1611 1611
1612 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1612 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1613 LHasCachedArrayIndexAndBranch* instr) { 1613 LHasCachedArrayIndexAndBranch* instr) {
1614 Register input = ToRegister(instr->input()); 1614 Register input = ToRegister(instr->InputAt(0));
1615 1615
1616 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1616 int true_block = chunk_->LookupDestination(instr->true_block_id());
1617 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1617 int false_block = chunk_->LookupDestination(instr->false_block_id());
1618 1618
1619 __ test(FieldOperand(input, String::kHashFieldOffset), 1619 __ test(FieldOperand(input, String::kHashFieldOffset),
1620 Immediate(String::kContainsCachedArrayIndexMask)); 1620 Immediate(String::kContainsCachedArrayIndexMask));
1621 EmitBranch(true_block, false_block, not_equal); 1621 EmitBranch(true_block, false_block, not_equal);
1622 } 1622 }
1623 1623
1624 1624
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 // booted. This routine isn't expected to work for random API-created 1673 // booted. This routine isn't expected to work for random API-created
1674 // classes and it doesn't have to because you can't access it with natives 1674 // classes and it doesn't have to because you can't access it with natives
1675 // syntax. Since both sides are symbols it is sufficient to use an identity 1675 // syntax. Since both sides are symbols it is sufficient to use an identity
1676 // comparison. 1676 // comparison.
1677 __ cmp(temp, class_name); 1677 __ cmp(temp, class_name);
1678 // End with the answer in the z flag. 1678 // End with the answer in the z flag.
1679 } 1679 }
1680 1680
1681 1681
1682 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1682 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1683 Register input = ToRegister(instr->input()); 1683 Register input = ToRegister(instr->InputAt(0));
1684 Register result = ToRegister(instr->result()); 1684 Register result = ToRegister(instr->result());
1685 ASSERT(input.is(result)); 1685 ASSERT(input.is(result));
1686 Register temp = ToRegister(instr->temporary()); 1686 Register temp = ToRegister(instr->TempAt(0));
1687 Handle<String> class_name = instr->hydrogen()->class_name(); 1687 Handle<String> class_name = instr->hydrogen()->class_name();
1688 NearLabel done; 1688 NearLabel done;
1689 Label is_true, is_false; 1689 Label is_true, is_false;
1690 1690
1691 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); 1691 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
1692 1692
1693 __ j(not_equal, &is_false); 1693 __ j(not_equal, &is_false);
1694 1694
1695 __ bind(&is_true); 1695 __ bind(&is_true);
1696 __ mov(result, Handle<Object>(Heap::true_value())); 1696 __ mov(result, Handle<Object>(Heap::true_value()));
1697 __ jmp(&done); 1697 __ jmp(&done);
1698 1698
1699 __ bind(&is_false); 1699 __ bind(&is_false);
1700 __ mov(result, Handle<Object>(Heap::false_value())); 1700 __ mov(result, Handle<Object>(Heap::false_value()));
1701 __ bind(&done); 1701 __ bind(&done);
1702 } 1702 }
1703 1703
1704 1704
1705 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1705 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1706 Register input = ToRegister(instr->input()); 1706 Register input = ToRegister(instr->InputAt(0));
1707 Register temp = ToRegister(instr->temporary()); 1707 Register temp = ToRegister(instr->TempAt(0));
1708 Register temp2 = ToRegister(instr->temporary2()); 1708 Register temp2 = ToRegister(instr->TempAt(1));
1709 if (input.is(temp)) { 1709 if (input.is(temp)) {
1710 // Swap. 1710 // Swap.
1711 Register swapper = temp; 1711 Register swapper = temp;
1712 temp = temp2; 1712 temp = temp2;
1713 temp2 = swapper; 1713 temp2 = swapper;
1714 } 1714 }
1715 Handle<String> class_name = instr->hydrogen()->class_name(); 1715 Handle<String> class_name = instr->hydrogen()->class_name();
1716 1716
1717 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1717 int true_block = chunk_->LookupDestination(instr->true_block_id());
1718 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1718 int false_block = chunk_->LookupDestination(instr->false_block_id());
1719 1719
1720 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1720 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1721 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1721 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1722 1722
1723 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 1723 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
1724 1724
1725 EmitBranch(true_block, false_block, equal); 1725 EmitBranch(true_block, false_block, equal);
1726 } 1726 }
1727 1727
1728 1728
1729 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1729 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1730 Register reg = ToRegister(instr->input()); 1730 Register reg = ToRegister(instr->InputAt(0));
1731 int true_block = instr->true_block_id(); 1731 int true_block = instr->true_block_id();
1732 int false_block = instr->false_block_id(); 1732 int false_block = instr->false_block_id();
1733 1733
1734 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 1734 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
1735 EmitBranch(true_block, false_block, equal); 1735 EmitBranch(true_block, false_block, equal);
1736 } 1736 }
1737 1737
1738 1738
1739 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1739 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1740 // Object and function are in fixed registers defined by the stub. 1740 // Object and function are in fixed registers defined by the stub.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 1777
1778 private: 1778 private:
1779 LInstanceOfKnownGlobal* instr_; 1779 LInstanceOfKnownGlobal* instr_;
1780 Label map_check_; 1780 Label map_check_;
1781 }; 1781 };
1782 1782
1783 DeferredInstanceOfKnownGlobal* deferred; 1783 DeferredInstanceOfKnownGlobal* deferred;
1784 deferred = new DeferredInstanceOfKnownGlobal(this, instr); 1784 deferred = new DeferredInstanceOfKnownGlobal(this, instr);
1785 1785
1786 Label done, false_result; 1786 Label done, false_result;
1787 Register object = ToRegister(instr->input()); 1787 Register object = ToRegister(instr->InputAt(0));
1788 Register temp = ToRegister(instr->temp()); 1788 Register temp = ToRegister(instr->TempAt(0));
1789 1789
1790 // A Smi is not instance of anything. 1790 // A Smi is not instance of anything.
1791 __ test(object, Immediate(kSmiTagMask)); 1791 __ test(object, Immediate(kSmiTagMask));
1792 __ j(zero, &false_result, not_taken); 1792 __ j(zero, &false_result, not_taken);
1793 1793
1794 // This is the inlined call site instanceof cache. The two occourences of the 1794 // This is the inlined call site instanceof cache. The two occourences of the
1795 // hole value will be patched to the last map/result pair generated by the 1795 // hole value will be patched to the last map/result pair generated by the
1796 // instanceof stub. 1796 // instanceof stub.
1797 NearLabel cache_miss; 1797 NearLabel cache_miss;
1798 Register map = ToRegister(instr->temp()); 1798 Register map = ToRegister(instr->TempAt(0));
1799 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 1799 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
1800 __ bind(deferred->map_check()); // Label for calculating code patching. 1800 __ bind(deferred->map_check()); // Label for calculating code patching.
1801 __ cmp(map, Factory::the_hole_value()); // Patched to cached map. 1801 __ cmp(map, Factory::the_hole_value()); // Patched to cached map.
1802 __ j(not_equal, &cache_miss, not_taken); 1802 __ j(not_equal, &cache_miss, not_taken);
1803 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false. 1803 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false.
1804 __ jmp(&done); 1804 __ jmp(&done);
1805 1805
1806 // The inlined call site cache did not match. Check null and string before 1806 // The inlined call site cache did not match. Check null and string before
1807 // calling the deferred code. 1807 // calling the deferred code.
1808 __ bind(&cache_miss); 1808 __ bind(&cache_miss);
(...skipping 27 matching lines...) Expand all
1836 flags | InstanceofStub::kArgsInRegisters); 1836 flags | InstanceofStub::kArgsInRegisters);
1837 flags = static_cast<InstanceofStub::Flags>( 1837 flags = static_cast<InstanceofStub::Flags>(
1838 flags | InstanceofStub::kCallSiteInlineCheck); 1838 flags | InstanceofStub::kCallSiteInlineCheck);
1839 flags = static_cast<InstanceofStub::Flags>( 1839 flags = static_cast<InstanceofStub::Flags>(
1840 flags | InstanceofStub::kReturnTrueFalseObject); 1840 flags | InstanceofStub::kReturnTrueFalseObject);
1841 InstanceofStub stub(flags); 1841 InstanceofStub stub(flags);
1842 1842
1843 // Get the temp register reserved by the instruction. This needs to be edi as 1843 // Get the temp register reserved by the instruction. This needs to be edi as
1844 // its slot of the pushing of safepoint registers is used to communicate the 1844 // its slot of the pushing of safepoint registers is used to communicate the
1845 // offset to the location of the map check. 1845 // offset to the location of the map check.
1846 Register temp = ToRegister(instr->temp()); 1846 Register temp = ToRegister(instr->TempAt(0));
1847 ASSERT(temp.is(edi)); 1847 ASSERT(temp.is(edi));
1848 __ mov(InstanceofStub::right(), Immediate(instr->function())); 1848 __ mov(InstanceofStub::right(), Immediate(instr->function()));
1849 static const int kAdditionalDelta = 13; 1849 static const int kAdditionalDelta = 13;
1850 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 1850 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
1851 Label before_push_delta; 1851 Label before_push_delta;
1852 __ bind(&before_push_delta); 1852 __ bind(&before_push_delta);
1853 __ mov(temp, Immediate(delta)); 1853 __ mov(temp, Immediate(delta));
1854 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp); 1854 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp);
1855 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 1855 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
1856 ASSERT_EQ(kAdditionalDelta, 1856 ASSERT_EQ(kAdditionalDelta,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 Register result = ToRegister(instr->result()); 1941 Register result = ToRegister(instr->result());
1942 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); 1942 __ mov(result, Operand::Cell(instr->hydrogen()->cell()));
1943 if (instr->hydrogen()->check_hole_value()) { 1943 if (instr->hydrogen()->check_hole_value()) {
1944 __ cmp(result, Factory::the_hole_value()); 1944 __ cmp(result, Factory::the_hole_value());
1945 DeoptimizeIf(equal, instr->environment()); 1945 DeoptimizeIf(equal, instr->environment());
1946 } 1946 }
1947 } 1947 }
1948 1948
1949 1949
1950 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 1950 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
1951 Register value = ToRegister(instr->input()); 1951 Register value = ToRegister(instr->InputAt(0));
1952 __ mov(Operand::Cell(instr->hydrogen()->cell()), value); 1952 __ mov(Operand::Cell(instr->hydrogen()->cell()), value);
1953 } 1953 }
1954 1954
1955 1955
1956 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 1956 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
1957 Register object = ToRegister(instr->input()); 1957 Register object = ToRegister(instr->InputAt(0));
1958 Register result = ToRegister(instr->result()); 1958 Register result = ToRegister(instr->result());
1959 if (instr->hydrogen()->is_in_object()) { 1959 if (instr->hydrogen()->is_in_object()) {
1960 __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); 1960 __ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
1961 } else { 1961 } else {
1962 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); 1962 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
1963 __ mov(result, FieldOperand(result, instr->hydrogen()->offset())); 1963 __ mov(result, FieldOperand(result, instr->hydrogen()->offset()));
1964 } 1964 }
1965 } 1965 }
1966 1966
1967 1967
1968 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 1968 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
1969 ASSERT(ToRegister(instr->object()).is(eax)); 1969 ASSERT(ToRegister(instr->object()).is(eax));
1970 ASSERT(ToRegister(instr->result()).is(eax)); 1970 ASSERT(ToRegister(instr->result()).is(eax));
1971 1971
1972 __ mov(ecx, instr->name()); 1972 __ mov(ecx, instr->name());
1973 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1973 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1974 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1974 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1975 } 1975 }
1976 1976
1977 1977
1978 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 1978 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
1979 Register function = ToRegister(instr->function()); 1979 Register function = ToRegister(instr->function());
1980 Register temp = ToRegister(instr->temporary()); 1980 Register temp = ToRegister(instr->TempAt(0));
1981 Register result = ToRegister(instr->result()); 1981 Register result = ToRegister(instr->result());
1982 1982
1983 // Check that the function really is a function. 1983 // Check that the function really is a function.
1984 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 1984 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
1985 DeoptimizeIf(not_equal, instr->environment()); 1985 DeoptimizeIf(not_equal, instr->environment());
1986 1986
1987 // Check whether the function has an instance prototype. 1987 // Check whether the function has an instance prototype.
1988 NearLabel non_instance; 1988 NearLabel non_instance;
1989 __ test_b(FieldOperand(result, Map::kBitFieldOffset), 1989 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
1990 1 << Map::kHasNonInstancePrototype); 1990 1 << Map::kHasNonInstancePrototype);
(...skipping 20 matching lines...) Expand all
2011 // in the function's map. 2011 // in the function's map.
2012 __ bind(&non_instance); 2012 __ bind(&non_instance);
2013 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 2013 __ mov(result, FieldOperand(result, Map::kConstructorOffset));
2014 2014
2015 // All done. 2015 // All done.
2016 __ bind(&done); 2016 __ bind(&done);
2017 } 2017 }
2018 2018
2019 2019
2020 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2020 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2021 ASSERT(instr->result()->Equals(instr->input())); 2021 ASSERT(instr->result()->Equals(instr->InputAt(0)));
2022 Register reg = ToRegister(instr->input()); 2022 Register reg = ToRegister(instr->InputAt(0));
2023 __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset)); 2023 __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset));
2024 if (FLAG_debug_code) { 2024 if (FLAG_debug_code) {
2025 NearLabel done; 2025 NearLabel done;
2026 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2026 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2027 Immediate(Factory::fixed_array_map())); 2027 Immediate(Factory::fixed_array_map()));
2028 __ j(equal, &done); 2028 __ j(equal, &done);
2029 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2029 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2030 Immediate(Factory::fixed_cow_array_map())); 2030 Immediate(Factory::fixed_cow_array_map()));
2031 __ Check(equal, "Check for fast elements failed."); 2031 __ Check(equal, "Check for fast elements failed.");
2032 __ bind(&done); 2032 __ bind(&done);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 __ bind(&adapted); 2092 __ bind(&adapted);
2093 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2093 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2094 2094
2095 // Result is the frame pointer for the frame if not adapted and for the real 2095 // Result is the frame pointer for the frame if not adapted and for the real
2096 // frame below the adaptor frame if adapted. 2096 // frame below the adaptor frame if adapted.
2097 __ bind(&done); 2097 __ bind(&done);
2098 } 2098 }
2099 2099
2100 2100
2101 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2101 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2102 Operand elem = ToOperand(instr->input()); 2102 Operand elem = ToOperand(instr->InputAt(0));
2103 Register result = ToRegister(instr->result()); 2103 Register result = ToRegister(instr->result());
2104 2104
2105 NearLabel done; 2105 NearLabel done;
2106 2106
2107 // If no arguments adaptor frame the number of arguments is fixed. 2107 // If no arguments adaptor frame the number of arguments is fixed.
2108 __ cmp(ebp, elem); 2108 __ cmp(ebp, elem);
2109 __ mov(result, Immediate(scope()->num_parameters())); 2109 __ mov(result, Immediate(scope()->num_parameters()));
2110 __ j(equal, &done); 2110 __ j(equal, &done);
2111 2111
2112 // Arguments adaptor frame present. Get argument length from there. 2112 // Arguments adaptor frame present. Get argument length from there.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 ASSERT(receiver.is(eax)); 2166 ASSERT(receiver.is(eax));
2167 v8::internal::ParameterCount actual(eax); 2167 v8::internal::ParameterCount actual(eax);
2168 SafepointGenerator safepoint_generator(this, 2168 SafepointGenerator safepoint_generator(this,
2169 instr->pointer_map(), 2169 instr->pointer_map(),
2170 Safepoint::kNoDeoptimizationIndex); 2170 Safepoint::kNoDeoptimizationIndex);
2171 __ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator); 2171 __ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator);
2172 } 2172 }
2173 2173
2174 2174
2175 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2175 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2176 LOperand* argument = instr->input(); 2176 LOperand* argument = instr->InputAt(0);
2177 if (argument->IsConstantOperand()) { 2177 if (argument->IsConstantOperand()) {
2178 __ push(ToImmediate(argument)); 2178 __ push(ToImmediate(argument));
2179 } else { 2179 } else {
2180 __ push(ToOperand(argument)); 2180 __ push(ToOperand(argument));
2181 } 2181 }
2182 } 2182 }
2183 2183
2184 2184
2185 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 2185 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
2186 Register result = ToRegister(instr->result()); 2186 Register result = ToRegister(instr->result());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 2232
2233 2233
2234 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2234 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2235 ASSERT(ToRegister(instr->result()).is(eax)); 2235 ASSERT(ToRegister(instr->result()).is(eax));
2236 __ mov(edi, instr->function()); 2236 __ mov(edi, instr->function());
2237 CallKnownFunction(instr->function(), instr->arity(), instr); 2237 CallKnownFunction(instr->function(), instr->arity(), instr);
2238 } 2238 }
2239 2239
2240 2240
2241 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2241 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2242 Register input_reg = ToRegister(instr->input()); 2242 Register input_reg = ToRegister(instr->InputAt(0));
2243 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 2243 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
2244 Factory::heap_number_map()); 2244 Factory::heap_number_map());
2245 DeoptimizeIf(not_equal, instr->environment()); 2245 DeoptimizeIf(not_equal, instr->environment());
2246 2246
2247 Label done; 2247 Label done;
2248 Register tmp = input_reg.is(eax) ? ecx : eax; 2248 Register tmp = input_reg.is(eax) ? ecx : eax;
2249 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; 2249 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx;
2250 2250
2251 // Preserve the value of all registers. 2251 // Preserve the value of all registers.
2252 __ PushSafepointRegisters(); 2252 __ PushSafepointRegisters();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2299 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2300 LUnaryMathOperation* instr) 2300 LUnaryMathOperation* instr)
2301 : LDeferredCode(codegen), instr_(instr) { } 2301 : LDeferredCode(codegen), instr_(instr) { }
2302 virtual void Generate() { 2302 virtual void Generate() {
2303 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2303 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2304 } 2304 }
2305 private: 2305 private:
2306 LUnaryMathOperation* instr_; 2306 LUnaryMathOperation* instr_;
2307 }; 2307 };
2308 2308
2309 ASSERT(instr->input()->Equals(instr->result())); 2309 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2310 Representation r = instr->hydrogen()->value()->representation(); 2310 Representation r = instr->hydrogen()->value()->representation();
2311 2311
2312 if (r.IsDouble()) { 2312 if (r.IsDouble()) {
2313 XMMRegister scratch = xmm0; 2313 XMMRegister scratch = xmm0;
2314 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2314 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2315 __ pxor(scratch, scratch); 2315 __ pxor(scratch, scratch);
2316 __ subsd(scratch, input_reg); 2316 __ subsd(scratch, input_reg);
2317 __ pand(input_reg, scratch); 2317 __ pand(input_reg, scratch);
2318 } else if (r.IsInteger32()) { 2318 } else if (r.IsInteger32()) {
2319 Register input_reg = ToRegister(instr->input()); 2319 Register input_reg = ToRegister(instr->InputAt(0));
2320 __ test(input_reg, Operand(input_reg)); 2320 __ test(input_reg, Operand(input_reg));
2321 Label is_positive; 2321 Label is_positive;
2322 __ j(not_sign, &is_positive); 2322 __ j(not_sign, &is_positive);
2323 __ neg(input_reg); 2323 __ neg(input_reg);
2324 __ test(input_reg, Operand(input_reg)); 2324 __ test(input_reg, Operand(input_reg));
2325 DeoptimizeIf(negative, instr->environment()); 2325 DeoptimizeIf(negative, instr->environment());
2326 __ bind(&is_positive); 2326 __ bind(&is_positive);
2327 } else { // Tagged case. 2327 } else { // Tagged case.
2328 DeferredMathAbsTaggedHeapNumber* deferred = 2328 DeferredMathAbsTaggedHeapNumber* deferred =
2329 new DeferredMathAbsTaggedHeapNumber(this, instr); 2329 new DeferredMathAbsTaggedHeapNumber(this, instr);
2330 Label not_smi; 2330 Label not_smi;
2331 Register input_reg = ToRegister(instr->input()); 2331 Register input_reg = ToRegister(instr->InputAt(0));
2332 // Smi check. 2332 // Smi check.
2333 __ test(input_reg, Immediate(kSmiTagMask)); 2333 __ test(input_reg, Immediate(kSmiTagMask));
2334 __ j(not_zero, deferred->entry()); 2334 __ j(not_zero, deferred->entry());
2335 __ test(input_reg, Operand(input_reg)); 2335 __ test(input_reg, Operand(input_reg));
2336 Label is_positive; 2336 Label is_positive;
2337 __ j(not_sign, &is_positive); 2337 __ j(not_sign, &is_positive);
2338 __ neg(input_reg); 2338 __ neg(input_reg);
2339 2339
2340 __ test(input_reg, Operand(input_reg)); 2340 __ test(input_reg, Operand(input_reg));
2341 DeoptimizeIf(negative, instr->environment()); 2341 DeoptimizeIf(negative, instr->environment());
2342 2342
2343 __ bind(&is_positive); 2343 __ bind(&is_positive);
2344 __ bind(deferred->exit()); 2344 __ bind(deferred->exit());
2345 } 2345 }
2346 } 2346 }
2347 2347
2348 2348
2349 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2349 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2350 XMMRegister xmm_scratch = xmm0; 2350 XMMRegister xmm_scratch = xmm0;
2351 Register output_reg = ToRegister(instr->result()); 2351 Register output_reg = ToRegister(instr->result());
2352 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2352 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2353 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. 2353 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register.
2354 __ ucomisd(input_reg, xmm_scratch); 2354 __ ucomisd(input_reg, xmm_scratch);
2355 2355
2356 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2356 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2357 DeoptimizeIf(below_equal, instr->environment()); 2357 DeoptimizeIf(below_equal, instr->environment());
2358 } else { 2358 } else {
2359 DeoptimizeIf(below, instr->environment()); 2359 DeoptimizeIf(below, instr->environment());
2360 } 2360 }
2361 2361
2362 // Use truncating instruction (OK because input is positive). 2362 // Use truncating instruction (OK because input is positive).
2363 __ cvttsd2si(output_reg, Operand(input_reg)); 2363 __ cvttsd2si(output_reg, Operand(input_reg));
2364 2364
2365 // Overflow is signalled with minint. 2365 // Overflow is signalled with minint.
2366 __ cmp(output_reg, 0x80000000u); 2366 __ cmp(output_reg, 0x80000000u);
2367 DeoptimizeIf(equal, instr->environment()); 2367 DeoptimizeIf(equal, instr->environment());
2368 } 2368 }
2369 2369
2370 2370
2371 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2371 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2372 XMMRegister xmm_scratch = xmm0; 2372 XMMRegister xmm_scratch = xmm0;
2373 Register output_reg = ToRegister(instr->result()); 2373 Register output_reg = ToRegister(instr->result());
2374 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2374 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2375 2375
2376 // xmm_scratch = 0.5 2376 // xmm_scratch = 0.5
2377 ExternalReference one_half = ExternalReference::address_of_one_half(); 2377 ExternalReference one_half = ExternalReference::address_of_one_half();
2378 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 2378 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
2379 2379
2380 // input = input + 0.5 2380 // input = input + 0.5
2381 __ addsd(input_reg, xmm_scratch); 2381 __ addsd(input_reg, xmm_scratch);
2382 2382
2383 // We need to return -0 for the input range [-0.5, 0[, otherwise 2383 // We need to return -0 for the input range [-0.5, 0[, otherwise
2384 // compute Math.floor(value + 0.5). 2384 // compute Math.floor(value + 0.5).
(...skipping 12 matching lines...) Expand all
2397 // Use truncating instruction (OK because input is positive). 2397 // Use truncating instruction (OK because input is positive).
2398 __ cvttsd2si(output_reg, Operand(input_reg)); 2398 __ cvttsd2si(output_reg, Operand(input_reg));
2399 2399
2400 // Overflow is signalled with minint. 2400 // Overflow is signalled with minint.
2401 __ cmp(output_reg, 0x80000000u); 2401 __ cmp(output_reg, 0x80000000u);
2402 DeoptimizeIf(equal, instr->environment()); 2402 DeoptimizeIf(equal, instr->environment());
2403 } 2403 }
2404 2404
2405 2405
2406 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2406 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2407 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2407 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2408 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2408 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2409 __ sqrtsd(input_reg, input_reg); 2409 __ sqrtsd(input_reg, input_reg);
2410 } 2410 }
2411 2411
2412 2412
2413 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 2413 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2414 XMMRegister xmm_scratch = xmm0; 2414 XMMRegister xmm_scratch = xmm0;
2415 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2415 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2416 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2416 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2417 ExternalReference negative_infinity = 2417 ExternalReference negative_infinity =
2418 ExternalReference::address_of_negative_infinity(); 2418 ExternalReference::address_of_negative_infinity();
2419 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity)); 2419 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
2420 __ ucomisd(xmm_scratch, input_reg); 2420 __ ucomisd(xmm_scratch, input_reg);
2421 DeoptimizeIf(equal, instr->environment()); 2421 DeoptimizeIf(equal, instr->environment());
2422 __ sqrtsd(input_reg, input_reg); 2422 __ sqrtsd(input_reg, input_reg);
2423 } 2423 }
2424 2424
2425 2425
2426 void LCodeGen::DoPower(LPower* instr) { 2426 void LCodeGen::DoPower(LPower* instr) {
2427 LOperand* left = instr->left(); 2427 LOperand* left = instr->InputAt(0);
2428 LOperand* right = instr->right(); 2428 LOperand* right = instr->InputAt(1);
2429 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 2429 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2430 Representation exponent_type = instr->hydrogen()->right()->representation(); 2430 Representation exponent_type = instr->hydrogen()->right()->representation();
2431 if (exponent_type.IsDouble()) { 2431 if (exponent_type.IsDouble()) {
2432 // It is safe to use ebx directly since the instruction is marked 2432 // It is safe to use ebx directly since the instruction is marked
2433 // as a call. 2433 // as a call.
2434 __ PrepareCallCFunction(4, ebx); 2434 __ PrepareCallCFunction(4, ebx);
2435 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); 2435 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2436 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right)); 2436 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
2437 __ CallCFunction(ExternalReference::power_double_double_function(), 4); 2437 __ CallCFunction(ExternalReference::power_double_double_function(), 4);
2438 } else if (exponent_type.IsInteger32()) { 2438 } else if (exponent_type.IsInteger32()) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2580 2580
2581 2581
2582 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 2582 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
2583 ASSERT(ToRegister(instr->result()).is(eax)); 2583 ASSERT(ToRegister(instr->result()).is(eax));
2584 __ mov(edi, instr->target()); 2584 __ mov(edi, instr->target());
2585 CallKnownFunction(instr->target(), instr->arity(), instr); 2585 CallKnownFunction(instr->target(), instr->arity(), instr);
2586 } 2586 }
2587 2587
2588 2588
2589 void LCodeGen::DoCallNew(LCallNew* instr) { 2589 void LCodeGen::DoCallNew(LCallNew* instr) {
2590 ASSERT(ToRegister(instr->input()).is(edi)); 2590 ASSERT(ToRegister(instr->InputAt(0)).is(edi));
2591 ASSERT(ToRegister(instr->result()).is(eax)); 2591 ASSERT(ToRegister(instr->result()).is(eax));
2592 2592
2593 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall)); 2593 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall));
2594 __ Set(eax, Immediate(instr->arity())); 2594 __ Set(eax, Immediate(instr->arity()));
2595 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); 2595 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
2596 } 2596 }
2597 2597
2598 2598
2599 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 2599 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
2600 CallRuntime(instr->function(), instr->arity(), instr); 2600 CallRuntime(instr->function(), instr->arity(), instr);
2601 } 2601 }
2602 2602
2603 2603
2604 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 2604 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
2605 Register object = ToRegister(instr->object()); 2605 Register object = ToRegister(instr->object());
2606 Register value = ToRegister(instr->value()); 2606 Register value = ToRegister(instr->value());
2607 int offset = instr->offset(); 2607 int offset = instr->offset();
2608 2608
2609 if (!instr->transition().is_null()) { 2609 if (!instr->transition().is_null()) {
2610 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 2610 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
2611 } 2611 }
2612 2612
2613 // Do the store. 2613 // Do the store.
2614 if (instr->is_in_object()) { 2614 if (instr->is_in_object()) {
2615 __ mov(FieldOperand(object, offset), value); 2615 __ mov(FieldOperand(object, offset), value);
2616 if (instr->needs_write_barrier()) { 2616 if (instr->needs_write_barrier()) {
2617 Register temp = ToRegister(instr->temp()); 2617 Register temp = ToRegister(instr->TempAt(0));
2618 // Update the write barrier for the object for in-object properties. 2618 // Update the write barrier for the object for in-object properties.
2619 __ RecordWrite(object, offset, value, temp); 2619 __ RecordWrite(object, offset, value, temp);
2620 } 2620 }
2621 } else { 2621 } else {
2622 Register temp = ToRegister(instr->temp()); 2622 Register temp = ToRegister(instr->TempAt(0));
2623 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 2623 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
2624 __ mov(FieldOperand(temp, offset), value); 2624 __ mov(FieldOperand(temp, offset), value);
2625 if (instr->needs_write_barrier()) { 2625 if (instr->needs_write_barrier()) {
2626 // Update the write barrier for the properties array. 2626 // Update the write barrier for the properties array.
2627 // object is used as a scratch register. 2627 // object is used as a scratch register.
2628 __ RecordWrite(temp, offset, value, object); 2628 __ RecordWrite(temp, offset, value, object);
2629 } 2629 }
2630 } 2630 }
2631 } 2631 }
2632 2632
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 ASSERT(ToRegister(instr->object()).is(edx)); 2676 ASSERT(ToRegister(instr->object()).is(edx));
2677 ASSERT(ToRegister(instr->key()).is(ecx)); 2677 ASSERT(ToRegister(instr->key()).is(ecx));
2678 ASSERT(ToRegister(instr->value()).is(eax)); 2678 ASSERT(ToRegister(instr->value()).is(eax));
2679 2679
2680 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 2680 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
2681 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2681 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2682 } 2682 }
2683 2683
2684 2684
2685 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2685 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
2686 LOperand* input = instr->input(); 2686 LOperand* input = instr->InputAt(0);
2687 ASSERT(input->IsRegister() || input->IsStackSlot()); 2687 ASSERT(input->IsRegister() || input->IsStackSlot());
2688 LOperand* output = instr->result(); 2688 LOperand* output = instr->result();
2689 ASSERT(output->IsDoubleRegister()); 2689 ASSERT(output->IsDoubleRegister());
2690 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 2690 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
2691 } 2691 }
2692 2692
2693 2693
2694 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 2694 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
2695 class DeferredNumberTagI: public LDeferredCode { 2695 class DeferredNumberTagI: public LDeferredCode {
2696 public: 2696 public:
2697 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 2697 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
2698 : LDeferredCode(codegen), instr_(instr) { } 2698 : LDeferredCode(codegen), instr_(instr) { }
2699 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 2699 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
2700 private: 2700 private:
2701 LNumberTagI* instr_; 2701 LNumberTagI* instr_;
2702 }; 2702 };
2703 2703
2704 LOperand* input = instr->input(); 2704 LOperand* input = instr->InputAt(0);
2705 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2705 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2706 Register reg = ToRegister(input); 2706 Register reg = ToRegister(input);
2707 2707
2708 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 2708 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
2709 __ SmiTag(reg); 2709 __ SmiTag(reg);
2710 __ j(overflow, deferred->entry()); 2710 __ j(overflow, deferred->entry());
2711 __ bind(deferred->exit()); 2711 __ bind(deferred->exit());
2712 } 2712 }
2713 2713
2714 2714
2715 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 2715 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
2716 Label slow; 2716 Label slow;
2717 Register reg = ToRegister(instr->input()); 2717 Register reg = ToRegister(instr->InputAt(0));
2718 Register tmp = reg.is(eax) ? ecx : eax; 2718 Register tmp = reg.is(eax) ? ecx : eax;
2719 2719
2720 // Preserve the value of all registers. 2720 // Preserve the value of all registers.
2721 __ PushSafepointRegisters(); 2721 __ PushSafepointRegisters();
2722 2722
2723 // There was overflow, so bits 30 and 31 of the original integer 2723 // There was overflow, so bits 30 and 31 of the original integer
2724 // disagree. Try to allocate a heap number in new space and store 2724 // disagree. Try to allocate a heap number in new space and store
2725 // the value in there. If that fails, call the runtime system. 2725 // the value in there. If that fails, call the runtime system.
2726 NearLabel done; 2726 NearLabel done;
2727 __ SmiUntag(reg); 2727 __ SmiUntag(reg);
(...skipping 29 matching lines...) Expand all
2757 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 2757 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
2758 class DeferredNumberTagD: public LDeferredCode { 2758 class DeferredNumberTagD: public LDeferredCode {
2759 public: 2759 public:
2760 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 2760 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
2761 : LDeferredCode(codegen), instr_(instr) { } 2761 : LDeferredCode(codegen), instr_(instr) { }
2762 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 2762 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
2763 private: 2763 private:
2764 LNumberTagD* instr_; 2764 LNumberTagD* instr_;
2765 }; 2765 };
2766 2766
2767 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2767 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2768 Register reg = ToRegister(instr->result()); 2768 Register reg = ToRegister(instr->result());
2769 Register tmp = ToRegister(instr->temp()); 2769 Register tmp = ToRegister(instr->TempAt(0));
2770 2770
2771 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 2771 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
2772 if (FLAG_inline_new) { 2772 if (FLAG_inline_new) {
2773 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 2773 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
2774 } else { 2774 } else {
2775 __ jmp(deferred->entry()); 2775 __ jmp(deferred->entry());
2776 } 2776 }
2777 __ bind(deferred->exit()); 2777 __ bind(deferred->exit());
2778 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 2778 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
2779 } 2779 }
2780 2780
2781 2781
2782 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 2782 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
2783 // TODO(3095996): Get rid of this. For now, we need to make the 2783 // TODO(3095996): Get rid of this. For now, we need to make the
2784 // result register contain a valid pointer because it is already 2784 // result register contain a valid pointer because it is already
2785 // contained in the register pointer map. 2785 // contained in the register pointer map.
2786 Register reg = ToRegister(instr->result()); 2786 Register reg = ToRegister(instr->result());
2787 __ Set(reg, Immediate(0)); 2787 __ Set(reg, Immediate(0));
2788 2788
2789 __ PushSafepointRegisters(); 2789 __ PushSafepointRegisters();
2790 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 2790 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
2791 RecordSafepointWithRegisters( 2791 RecordSafepointWithRegisters(
2792 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 2792 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
2793 __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), eax); 2793 __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), eax);
2794 __ PopSafepointRegisters(); 2794 __ PopSafepointRegisters();
2795 } 2795 }
2796 2796
2797 2797
2798 void LCodeGen::DoSmiTag(LSmiTag* instr) { 2798 void LCodeGen::DoSmiTag(LSmiTag* instr) {
2799 LOperand* input = instr->input(); 2799 LOperand* input = instr->InputAt(0);
2800 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2800 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2801 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 2801 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
2802 __ SmiTag(ToRegister(input)); 2802 __ SmiTag(ToRegister(input));
2803 } 2803 }
2804 2804
2805 2805
2806 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 2806 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
2807 LOperand* input = instr->input(); 2807 LOperand* input = instr->InputAt(0);
2808 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2808 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2809 if (instr->needs_check()) { 2809 if (instr->needs_check()) {
2810 __ test(ToRegister(input), Immediate(kSmiTagMask)); 2810 __ test(ToRegister(input), Immediate(kSmiTagMask));
2811 DeoptimizeIf(not_zero, instr->environment()); 2811 DeoptimizeIf(not_zero, instr->environment());
2812 } 2812 }
2813 __ SmiUntag(ToRegister(input)); 2813 __ SmiUntag(ToRegister(input));
2814 } 2814 }
2815 2815
2816 2816
2817 void LCodeGen::EmitNumberUntagD(Register input_reg, 2817 void LCodeGen::EmitNumberUntagD(Register input_reg,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 2857 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
2858 : LDeferredCode(codegen), instr_(instr) { } 2858 : LDeferredCode(codegen), instr_(instr) { }
2859 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 2859 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
2860 private: 2860 private:
2861 LTaggedToI* instr_; 2861 LTaggedToI* instr_;
2862 }; 2862 };
2863 2863
2864 2864
2865 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 2865 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
2866 NearLabel done, heap_number; 2866 NearLabel done, heap_number;
2867 Register input_reg = ToRegister(instr->input()); 2867 Register input_reg = ToRegister(instr->InputAt(0));
2868 2868
2869 // Heap number map check. 2869 // Heap number map check.
2870 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 2870 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
2871 Factory::heap_number_map()); 2871 Factory::heap_number_map());
2872 2872
2873 if (instr->truncating()) { 2873 if (instr->truncating()) {
2874 __ j(equal, &heap_number); 2874 __ j(equal, &heap_number);
2875 // Check for undefined. Undefined is converted to zero for truncating 2875 // Check for undefined. Undefined is converted to zero for truncating
2876 // conversions. 2876 // conversions.
2877 __ cmp(input_reg, Factory::undefined_value()); 2877 __ cmp(input_reg, Factory::undefined_value());
(...skipping 22 matching lines...) Expand all
2900 2900
2901 // Reserve space for 64 bit answer. 2901 // Reserve space for 64 bit answer.
2902 __ bind(&convert); 2902 __ bind(&convert);
2903 __ sub(Operand(esp), Immediate(kDoubleSize)); 2903 __ sub(Operand(esp), Immediate(kDoubleSize));
2904 // Do conversion, which cannot fail because we checked the exponent. 2904 // Do conversion, which cannot fail because we checked the exponent.
2905 __ fisttp_d(Operand(esp, 0)); 2905 __ fisttp_d(Operand(esp, 0));
2906 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 2906 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
2907 __ add(Operand(esp), Immediate(kDoubleSize)); 2907 __ add(Operand(esp), Immediate(kDoubleSize));
2908 } else { 2908 } else {
2909 NearLabel deopt; 2909 NearLabel deopt;
2910 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 2910 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
2911 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2911 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
2912 __ cvttsd2si(input_reg, Operand(xmm0)); 2912 __ cvttsd2si(input_reg, Operand(xmm0));
2913 __ cmp(input_reg, 0x80000000u); 2913 __ cmp(input_reg, 0x80000000u);
2914 __ j(not_equal, &done); 2914 __ j(not_equal, &done);
2915 // Check if the input was 0x8000000 (kMinInt). 2915 // Check if the input was 0x8000000 (kMinInt).
2916 // If no, then we got an overflow and we deoptimize. 2916 // If no, then we got an overflow and we deoptimize.
2917 ExternalReference min_int = ExternalReference::address_of_min_int(); 2917 ExternalReference min_int = ExternalReference::address_of_min_int();
2918 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 2918 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
2919 __ ucomisd(xmm_temp, xmm0); 2919 __ ucomisd(xmm_temp, xmm0);
2920 DeoptimizeIf(not_equal, instr->environment()); 2920 DeoptimizeIf(not_equal, instr->environment());
2921 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2921 DeoptimizeIf(parity_even, instr->environment()); // NaN.
2922 } 2922 }
2923 } else { 2923 } else {
2924 // Deoptimize if we don't have a heap number. 2924 // Deoptimize if we don't have a heap number.
2925 DeoptimizeIf(not_equal, instr->environment()); 2925 DeoptimizeIf(not_equal, instr->environment());
2926 2926
2927 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 2927 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
2928 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2928 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
2929 __ cvttsd2si(input_reg, Operand(xmm0)); 2929 __ cvttsd2si(input_reg, Operand(xmm0));
2930 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 2930 __ cvtsi2sd(xmm_temp, Operand(input_reg));
2931 __ ucomisd(xmm0, xmm_temp); 2931 __ ucomisd(xmm0, xmm_temp);
2932 DeoptimizeIf(not_equal, instr->environment()); 2932 DeoptimizeIf(not_equal, instr->environment());
2933 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2933 DeoptimizeIf(parity_even, instr->environment()); // NaN.
2934 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2934 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2935 __ test(input_reg, Operand(input_reg)); 2935 __ test(input_reg, Operand(input_reg));
2936 __ j(not_zero, &done); 2936 __ j(not_zero, &done);
2937 __ movmskpd(input_reg, xmm0); 2937 __ movmskpd(input_reg, xmm0);
2938 __ and_(input_reg, 1); 2938 __ and_(input_reg, 1);
2939 DeoptimizeIf(not_zero, instr->environment()); 2939 DeoptimizeIf(not_zero, instr->environment());
2940 } 2940 }
2941 } 2941 }
2942 __ bind(&done); 2942 __ bind(&done);
2943 } 2943 }
2944 2944
2945 2945
2946 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 2946 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
2947 LOperand* input = instr->input(); 2947 LOperand* input = instr->InputAt(0);
2948 ASSERT(input->IsRegister()); 2948 ASSERT(input->IsRegister());
2949 ASSERT(input->Equals(instr->result())); 2949 ASSERT(input->Equals(instr->result()));
2950 2950
2951 Register input_reg = ToRegister(input); 2951 Register input_reg = ToRegister(input);
2952 2952
2953 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); 2953 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
2954 2954
2955 // Smi check. 2955 // Smi check.
2956 __ test(input_reg, Immediate(kSmiTagMask)); 2956 __ test(input_reg, Immediate(kSmiTagMask));
2957 __ j(not_zero, deferred->entry()); 2957 __ j(not_zero, deferred->entry());
2958 2958
2959 // Smi to int32 conversion 2959 // Smi to int32 conversion
2960 __ SmiUntag(input_reg); // Untag smi. 2960 __ SmiUntag(input_reg); // Untag smi.
2961 2961
2962 __ bind(deferred->exit()); 2962 __ bind(deferred->exit());
2963 } 2963 }
2964 2964
2965 2965
2966 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 2966 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
2967 LOperand* input = instr->input(); 2967 LOperand* input = instr->InputAt(0);
2968 ASSERT(input->IsRegister()); 2968 ASSERT(input->IsRegister());
2969 LOperand* result = instr->result(); 2969 LOperand* result = instr->result();
2970 ASSERT(result->IsDoubleRegister()); 2970 ASSERT(result->IsDoubleRegister());
2971 2971
2972 Register input_reg = ToRegister(input); 2972 Register input_reg = ToRegister(input);
2973 XMMRegister result_reg = ToDoubleRegister(result); 2973 XMMRegister result_reg = ToDoubleRegister(result);
2974 2974
2975 EmitNumberUntagD(input_reg, result_reg, instr->environment()); 2975 EmitNumberUntagD(input_reg, result_reg, instr->environment());
2976 } 2976 }
2977 2977
2978 2978
2979 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 2979 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
2980 LOperand* input = instr->input(); 2980 LOperand* input = instr->InputAt(0);
2981 ASSERT(input->IsDoubleRegister()); 2981 ASSERT(input->IsDoubleRegister());
2982 LOperand* result = instr->result(); 2982 LOperand* result = instr->result();
2983 ASSERT(result->IsRegister()); 2983 ASSERT(result->IsRegister());
2984 2984
2985 XMMRegister input_reg = ToDoubleRegister(input); 2985 XMMRegister input_reg = ToDoubleRegister(input);
2986 Register result_reg = ToRegister(result); 2986 Register result_reg = ToRegister(result);
2987 2987
2988 if (instr->truncating()) { 2988 if (instr->truncating()) {
2989 // Performs a truncating conversion of a floating point number as used by 2989 // Performs a truncating conversion of a floating point number as used by
2990 // the JS bitwise operations. 2990 // the JS bitwise operations.
(...skipping 17 matching lines...) Expand all
3008 DeoptimizeIf(no_condition, instr->environment()); 3008 DeoptimizeIf(no_condition, instr->environment());
3009 __ bind(&convert); 3009 __ bind(&convert);
3010 // Do conversion, which cannot fail because we checked the exponent. 3010 // Do conversion, which cannot fail because we checked the exponent.
3011 __ fld_d(Operand(esp, 0)); 3011 __ fld_d(Operand(esp, 0));
3012 __ fisttp_d(Operand(esp, 0)); 3012 __ fisttp_d(Operand(esp, 0));
3013 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 3013 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
3014 __ add(Operand(esp), Immediate(kDoubleSize)); 3014 __ add(Operand(esp), Immediate(kDoubleSize));
3015 __ bind(&done); 3015 __ bind(&done);
3016 } else { 3016 } else {
3017 NearLabel done; 3017 NearLabel done;
3018 Register temp_reg = ToRegister(instr->temporary()); 3018 Register temp_reg = ToRegister(instr->TempAt(0));
3019 XMMRegister xmm_scratch = xmm0; 3019 XMMRegister xmm_scratch = xmm0;
3020 3020
3021 // If cvttsd2si succeeded, we're done. Otherwise, we attempt 3021 // If cvttsd2si succeeded, we're done. Otherwise, we attempt
3022 // manual conversion. 3022 // manual conversion.
3023 __ j(not_equal, &done); 3023 __ j(not_equal, &done);
3024 3024
3025 // Get high 32 bits of the input in result_reg and temp_reg. 3025 // Get high 32 bits of the input in result_reg and temp_reg.
3026 __ pshufd(xmm_scratch, input_reg, 1); 3026 __ pshufd(xmm_scratch, input_reg, 1);
3027 __ movd(Operand(temp_reg), xmm_scratch); 3027 __ movd(Operand(temp_reg), xmm_scratch);
3028 __ mov(result_reg, temp_reg); 3028 __ mov(result_reg, temp_reg);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3087 // deoptimize. 3087 // deoptimize.
3088 __ and_(result_reg, 1); 3088 __ and_(result_reg, 1);
3089 DeoptimizeIf(not_zero, instr->environment()); 3089 DeoptimizeIf(not_zero, instr->environment());
3090 } 3090 }
3091 __ bind(&done); 3091 __ bind(&done);
3092 } 3092 }
3093 } 3093 }
3094 3094
3095 3095
3096 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 3096 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
3097 LOperand* input = instr->input(); 3097 LOperand* input = instr->InputAt(0);
3098 ASSERT(input->IsRegister()); 3098 ASSERT(input->IsRegister());
3099 __ test(ToRegister(input), Immediate(kSmiTagMask)); 3099 __ test(ToRegister(input), Immediate(kSmiTagMask));
3100 DeoptimizeIf(instr->condition(), instr->environment()); 3100 DeoptimizeIf(instr->condition(), instr->environment());
3101 } 3101 }
3102 3102
3103 3103
3104 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3104 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3105 Register input = ToRegister(instr->input()); 3105 Register input = ToRegister(instr->InputAt(0));
3106 Register temp = ToRegister(instr->temp()); 3106 Register temp = ToRegister(instr->TempAt(0));
3107 InstanceType first = instr->hydrogen()->first(); 3107 InstanceType first = instr->hydrogen()->first();
3108 InstanceType last = instr->hydrogen()->last(); 3108 InstanceType last = instr->hydrogen()->last();
3109 3109
3110 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 3110 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
3111 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3111 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3112 static_cast<int8_t>(first)); 3112 static_cast<int8_t>(first));
3113 3113
3114 // If there is only one type in the interval check for equality. 3114 // If there is only one type in the interval check for equality.
3115 if (first == last) { 3115 if (first == last) {
3116 DeoptimizeIf(not_equal, instr->environment()); 3116 DeoptimizeIf(not_equal, instr->environment());
3117 } else { 3117 } else {
3118 DeoptimizeIf(below, instr->environment()); 3118 DeoptimizeIf(below, instr->environment());
3119 // Omit check for the last type. 3119 // Omit check for the last type.
3120 if (last != LAST_TYPE) { 3120 if (last != LAST_TYPE) {
3121 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3121 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3122 static_cast<int8_t>(last)); 3122 static_cast<int8_t>(last));
3123 DeoptimizeIf(above, instr->environment()); 3123 DeoptimizeIf(above, instr->environment());
3124 } 3124 }
3125 } 3125 }
3126 } 3126 }
3127 3127
3128 3128
3129 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 3129 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
3130 ASSERT(instr->input()->IsRegister()); 3130 ASSERT(instr->InputAt(0)->IsRegister());
3131 Register reg = ToRegister(instr->input()); 3131 Register reg = ToRegister(instr->InputAt(0));
3132 __ cmp(reg, instr->hydrogen()->target()); 3132 __ cmp(reg, instr->hydrogen()->target());
3133 DeoptimizeIf(not_equal, instr->environment()); 3133 DeoptimizeIf(not_equal, instr->environment());
3134 } 3134 }
3135 3135
3136 3136
3137 void LCodeGen::DoCheckMap(LCheckMap* instr) { 3137 void LCodeGen::DoCheckMap(LCheckMap* instr) {
3138 LOperand* input = instr->input(); 3138 LOperand* input = instr->InputAt(0);
3139 ASSERT(input->IsRegister()); 3139 ASSERT(input->IsRegister());
3140 Register reg = ToRegister(input); 3140 Register reg = ToRegister(input);
3141 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 3141 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
3142 instr->hydrogen()->map()); 3142 instr->hydrogen()->map());
3143 DeoptimizeIf(not_equal, instr->environment()); 3143 DeoptimizeIf(not_equal, instr->environment());
3144 } 3144 }
3145 3145
3146 3146
3147 void LCodeGen::LoadPrototype(Register result, Handle<JSObject> prototype) { 3147 void LCodeGen::LoadPrototype(Register result, Handle<JSObject> prototype) {
3148 if (Heap::InNewSpace(*prototype)) { 3148 if (Heap::InNewSpace(*prototype)) {
3149 Handle<JSGlobalPropertyCell> cell = 3149 Handle<JSGlobalPropertyCell> cell =
3150 Factory::NewJSGlobalPropertyCell(prototype); 3150 Factory::NewJSGlobalPropertyCell(prototype);
3151 __ mov(result, Operand::Cell(cell)); 3151 __ mov(result, Operand::Cell(cell));
3152 } else { 3152 } else {
3153 __ mov(result, prototype); 3153 __ mov(result, prototype);
3154 } 3154 }
3155 } 3155 }
3156 3156
3157 3157
3158 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 3158 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
3159 Register reg = ToRegister(instr->temp()); 3159 Register reg = ToRegister(instr->TempAt(0));
3160 3160
3161 Handle<JSObject> holder = instr->holder(); 3161 Handle<JSObject> holder = instr->holder();
3162 Handle<JSObject> current_prototype = instr->prototype(); 3162 Handle<JSObject> current_prototype = instr->prototype();
3163 3163
3164 // Load prototype object. 3164 // Load prototype object.
3165 LoadPrototype(reg, current_prototype); 3165 LoadPrototype(reg, current_prototype);
3166 3166
3167 // Check prototype maps up to the holder. 3167 // Check prototype maps up to the holder.
3168 while (!current_prototype.is_identical_to(holder)) { 3168 while (!current_prototype.is_identical_to(holder)) {
3169 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 3169 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
3293 __ push(Immediate(shared_info)); 3293 __ push(Immediate(shared_info));
3294 __ push(Immediate(pretenure 3294 __ push(Immediate(pretenure
3295 ? Factory::true_value() 3295 ? Factory::true_value()
3296 : Factory::false_value())); 3296 : Factory::false_value()));
3297 CallRuntime(Runtime::kNewClosure, 3, instr); 3297 CallRuntime(Runtime::kNewClosure, 3, instr);
3298 } 3298 }
3299 } 3299 }
3300 3300
3301 3301
3302 void LCodeGen::DoTypeof(LTypeof* instr) { 3302 void LCodeGen::DoTypeof(LTypeof* instr) {
3303 LOperand* input = instr->input(); 3303 LOperand* input = instr->InputAt(0);
3304 if (input->IsConstantOperand()) { 3304 if (input->IsConstantOperand()) {
3305 __ push(ToImmediate(input)); 3305 __ push(ToImmediate(input));
3306 } else { 3306 } else {
3307 __ push(ToOperand(input)); 3307 __ push(ToOperand(input));
3308 } 3308 }
3309 CallRuntime(Runtime::kTypeof, 1, instr); 3309 CallRuntime(Runtime::kTypeof, 1, instr);
3310 } 3310 }
3311 3311
3312 3312
3313 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { 3313 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
3314 Register input = ToRegister(instr->input()); 3314 Register input = ToRegister(instr->InputAt(0));
3315 Register result = ToRegister(instr->result()); 3315 Register result = ToRegister(instr->result());
3316 Label true_label; 3316 Label true_label;
3317 Label false_label; 3317 Label false_label;
3318 NearLabel done; 3318 NearLabel done;
3319 3319
3320 Condition final_branch_condition = EmitTypeofIs(&true_label, 3320 Condition final_branch_condition = EmitTypeofIs(&true_label,
3321 &false_label, 3321 &false_label,
3322 input, 3322 input,
3323 instr->type_literal()); 3323 instr->type_literal());
3324 __ j(final_branch_condition, &true_label); 3324 __ j(final_branch_condition, &true_label);
3325 __ bind(&false_label); 3325 __ bind(&false_label);
3326 __ mov(result, Handle<Object>(Heap::false_value())); 3326 __ mov(result, Handle<Object>(Heap::false_value()));
3327 __ jmp(&done); 3327 __ jmp(&done);
3328 3328
3329 __ bind(&true_label); 3329 __ bind(&true_label);
3330 __ mov(result, Handle<Object>(Heap::true_value())); 3330 __ mov(result, Handle<Object>(Heap::true_value()));
3331 3331
3332 __ bind(&done); 3332 __ bind(&done);
3333 } 3333 }
3334 3334
3335 3335
3336 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 3336 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
3337 Register input = ToRegister(instr->input()); 3337 Register input = ToRegister(instr->InputAt(0));
3338 int true_block = chunk_->LookupDestination(instr->true_block_id()); 3338 int true_block = chunk_->LookupDestination(instr->true_block_id());
3339 int false_block = chunk_->LookupDestination(instr->false_block_id()); 3339 int false_block = chunk_->LookupDestination(instr->false_block_id());
3340 Label* true_label = chunk_->GetAssemblyLabel(true_block); 3340 Label* true_label = chunk_->GetAssemblyLabel(true_block);
3341 Label* false_label = chunk_->GetAssemblyLabel(false_block); 3341 Label* false_label = chunk_->GetAssemblyLabel(false_block);
3342 3342
3343 Condition final_branch_condition = EmitTypeofIs(true_label, 3343 Condition final_branch_condition = EmitTypeofIs(true_label,
3344 false_label, 3344 false_label,
3345 input, 3345 input,
3346 instr->type_literal()); 3346 instr->type_literal());
3347 3347
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 ASSERT(osr_pc_offset_ == -1); 3481 ASSERT(osr_pc_offset_ == -1);
3482 osr_pc_offset_ = masm()->pc_offset(); 3482 osr_pc_offset_ = masm()->pc_offset();
3483 } 3483 }
3484 3484
3485 3485
3486 #undef __ 3486 #undef __
3487 3487
3488 } } // namespace v8::internal 3488 } } // namespace v8::internal
3489 3489
3490 #endif // V8_TARGET_ARCH_IA32 3490 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698