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

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

Issue 6321012: Version 3.0.9... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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 | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 codegen_->RecordSafepoint(pointers_, deoptimization_index_); 51 codegen_->RecordSafepoint(pointers_, deoptimization_index_);
52 } 52 }
53 53
54 private: 54 private:
55 LCodeGen* codegen_; 55 LCodeGen* codegen_;
56 LPointerMap* pointers_; 56 LPointerMap* pointers_;
57 int deoptimization_index_; 57 int deoptimization_index_;
58 }; 58 };
59 59
60 60
61 class LGapNode: public ZoneObject {
62 public:
63 explicit LGapNode(LOperand* operand)
64 : operand_(operand), resolved_(false), visited_id_(-1) { }
65
66 LOperand* operand() const { return operand_; }
67 bool IsResolved() const { return !IsAssigned() || resolved_; }
68 void MarkResolved() {
69 ASSERT(!IsResolved());
70 resolved_ = true;
71 }
72 int visited_id() const { return visited_id_; }
73 void set_visited_id(int id) {
74 ASSERT(id > visited_id_);
75 visited_id_ = id;
76 }
77
78 bool IsAssigned() const { return assigned_from_.is_set(); }
79 LGapNode* assigned_from() const { return assigned_from_.get(); }
80 void set_assigned_from(LGapNode* n) { assigned_from_.set(n); }
81
82 private:
83 LOperand* operand_;
84 SetOncePointer<LGapNode> assigned_from_;
85 bool resolved_;
86 int visited_id_;
87 };
88
89
90 LGapResolver::LGapResolver()
91 : nodes_(32),
92 identified_cycles_(4),
93 result_(16),
94 next_visited_id_(0) {
95 }
96
97
98 const ZoneList<LMoveOperands>* LGapResolver::Resolve(
99 const ZoneList<LMoveOperands>* moves,
100 LOperand* marker_operand) {
101 nodes_.Rewind(0);
102 identified_cycles_.Rewind(0);
103 result_.Rewind(0);
104 next_visited_id_ = 0;
105
106 for (int i = 0; i < moves->length(); ++i) {
107 LMoveOperands move = moves->at(i);
108 if (!move.IsRedundant()) RegisterMove(move);
109 }
110
111 for (int i = 0; i < identified_cycles_.length(); ++i) {
112 ResolveCycle(identified_cycles_[i], marker_operand);
113 }
114
115 int unresolved_nodes;
116 do {
117 unresolved_nodes = 0;
118 for (int j = 0; j < nodes_.length(); j++) {
119 LGapNode* node = nodes_[j];
120 if (!node->IsResolved() && node->assigned_from()->IsResolved()) {
121 AddResultMove(node->assigned_from(), node);
122 node->MarkResolved();
123 }
124 if (!node->IsResolved()) ++unresolved_nodes;
125 }
126 } while (unresolved_nodes > 0);
127 return &result_;
128 }
129
130
131 void LGapResolver::AddResultMove(LGapNode* from, LGapNode* to) {
132 AddResultMove(from->operand(), to->operand());
133 }
134
135
136 void LGapResolver::AddResultMove(LOperand* from, LOperand* to) {
137 result_.Add(LMoveOperands(from, to));
138 }
139
140
141 void LGapResolver::ResolveCycle(LGapNode* start, LOperand* marker_operand) {
142 ZoneList<LOperand*> cycle_operands(8);
143 cycle_operands.Add(marker_operand);
144 LGapNode* cur = start;
145 do {
146 cur->MarkResolved();
147 cycle_operands.Add(cur->operand());
148 cur = cur->assigned_from();
149 } while (cur != start);
150 cycle_operands.Add(marker_operand);
151
152 for (int i = cycle_operands.length() - 1; i > 0; --i) {
153 LOperand* from = cycle_operands[i];
154 LOperand* to = cycle_operands[i - 1];
155 AddResultMove(from, to);
156 }
157 }
158
159
160 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b, int visited_id) {
161 ASSERT(a != b);
162 LGapNode* cur = a;
163 while (cur != b && cur->visited_id() != visited_id && cur->IsAssigned()) {
164 cur->set_visited_id(visited_id);
165 cur = cur->assigned_from();
166 }
167
168 return cur == b;
169 }
170
171
172 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b) {
173 ASSERT(a != b);
174 return CanReach(a, b, next_visited_id_++);
175 }
176
177
178 void LGapResolver::RegisterMove(LMoveOperands move) {
179 if (move.from()->IsConstantOperand()) {
180 // Constant moves should be last in the machine code. Therefore add them
181 // first to the result set.
182 AddResultMove(move.from(), move.to());
183 } else {
184 LGapNode* from = LookupNode(move.from());
185 LGapNode* to = LookupNode(move.to());
186 if (to->IsAssigned() && to->assigned_from() == from) {
187 move.Eliminate();
188 return;
189 }
190 ASSERT(!to->IsAssigned());
191 if (CanReach(from, to)) {
192 // This introduces a cycle. Save.
193 identified_cycles_.Add(from);
194 }
195 to->set_assigned_from(from);
196 }
197 }
198
199
200 LGapNode* LGapResolver::LookupNode(LOperand* operand) {
201 for (int i = 0; i < nodes_.length(); ++i) {
202 if (nodes_[i]->operand()->Equals(operand)) return nodes_[i];
203 }
204
205 // No node found => create a new one.
206 LGapNode* result = new LGapNode(operand);
207 nodes_.Add(result);
208 return result;
209 }
210
211
212 #define __ masm()-> 61 #define __ masm()->
213 62
214 bool LCodeGen::GenerateCode() { 63 bool LCodeGen::GenerateCode() {
215 HPhase phase("Code generation", chunk()); 64 HPhase phase("Code generation", chunk());
216 ASSERT(is_unused()); 65 ASSERT(is_unused());
217 status_ = GENERATING; 66 status_ = GENERATING;
218 CpuFeatures::Scope scope(SSE2); 67 CpuFeatures::Scope scope(SSE2);
219 return GeneratePrologue() && 68 return GeneratePrologue() &&
220 GenerateBody() && 69 GenerateBody() &&
221 GenerateDeferredCode() && 70 GenerateDeferredCode() &&
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // Local or spill slot. Skip the frame pointer, function, and 269 // Local or spill slot. Skip the frame pointer, function, and
421 // context in the fixed part of the frame. 270 // context in the fixed part of the frame.
422 return Operand(ebp, -(index + 3) * kPointerSize); 271 return Operand(ebp, -(index + 3) * kPointerSize);
423 } else { 272 } else {
424 // Incoming parameter. Skip the return address. 273 // Incoming parameter. Skip the return address.
425 return Operand(ebp, -(index - 1) * kPointerSize); 274 return Operand(ebp, -(index - 1) * kPointerSize);
426 } 275 }
427 } 276 }
428 277
429 278
279 Operand LCodeGen::HighOperand(LOperand* op) {
280 ASSERT(op->IsDoubleStackSlot());
281 int index = op->index();
282 int offset = (index >= 0) ? index + 3 : index - 1;
283 return Operand(ebp, -offset * kPointerSize);
284 }
285
286
430 void LCodeGen::WriteTranslation(LEnvironment* environment, 287 void LCodeGen::WriteTranslation(LEnvironment* environment,
431 Translation* translation) { 288 Translation* translation) {
432 if (environment == NULL) return; 289 if (environment == NULL) return;
433 290
434 // The translation includes one command per value in the environment. 291 // The translation includes one command per value in the environment.
435 int translation_size = environment->values()->length(); 292 int translation_size = environment->values()->length();
436 // The output frame height does not include the parameters. 293 // The output frame height does not include the parameters.
437 int height = translation_size - environment->parameter_count(); 294 int height = translation_size - environment->parameter_count();
438 295
439 WriteTranslation(environment->outer(), translation); 296 WriteTranslation(environment->outer(), translation);
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 } else { 612 } else {
756 Comment(";;; B%d", label->block_id()); 613 Comment(";;; B%d", label->block_id());
757 } 614 }
758 __ bind(label->label()); 615 __ bind(label->label());
759 current_block_ = label->block_id(); 616 current_block_ = label->block_id();
760 LCodeGen::DoGap(label); 617 LCodeGen::DoGap(label);
761 } 618 }
762 619
763 620
764 void LCodeGen::DoParallelMove(LParallelMove* move) { 621 void LCodeGen::DoParallelMove(LParallelMove* move) {
765 // xmm0 must always be a scratch register. 622 resolver_.Resolve(move);
766 XMMRegister xmm_scratch = xmm0;
767 LUnallocated marker_operand(LUnallocated::NONE);
768
769 Register cpu_scratch = esi;
770 bool destroys_cpu_scratch = false;
771
772 const ZoneList<LMoveOperands>* moves =
773 resolver_.Resolve(move->move_operands(), &marker_operand);
774 for (int i = moves->length() - 1; i >= 0; --i) {
775 LMoveOperands move = moves->at(i);
776 LOperand* from = move.from();
777 LOperand* to = move.to();
778 ASSERT(!from->IsDoubleRegister() ||
779 !ToDoubleRegister(from).is(xmm_scratch));
780 ASSERT(!to->IsDoubleRegister() || !ToDoubleRegister(to).is(xmm_scratch));
781 ASSERT(!from->IsRegister() || !ToRegister(from).is(cpu_scratch));
782 ASSERT(!to->IsRegister() || !ToRegister(to).is(cpu_scratch));
783 if (from->IsConstantOperand()) {
784 __ mov(ToOperand(to), ToImmediate(from));
785 } else if (from == &marker_operand) {
786 if (to->IsRegister() || to->IsStackSlot()) {
787 __ mov(ToOperand(to), cpu_scratch);
788 ASSERT(destroys_cpu_scratch);
789 } else {
790 ASSERT(to->IsDoubleRegister() || to->IsDoubleStackSlot());
791 __ movdbl(ToOperand(to), xmm_scratch);
792 }
793 } else if (to == &marker_operand) {
794 if (from->IsRegister() || from->IsStackSlot()) {
795 __ mov(cpu_scratch, ToOperand(from));
796 destroys_cpu_scratch = true;
797 } else {
798 ASSERT(from->IsDoubleRegister() || from->IsDoubleStackSlot());
799 __ movdbl(xmm_scratch, ToOperand(from));
800 }
801 } else if (from->IsRegister()) {
802 __ mov(ToOperand(to), ToRegister(from));
803 } else if (to->IsRegister()) {
804 __ mov(ToRegister(to), ToOperand(from));
805 } else if (from->IsStackSlot()) {
806 ASSERT(to->IsStackSlot());
807 __ push(eax);
808 __ mov(eax, ToOperand(from));
809 __ mov(ToOperand(to), eax);
810 __ pop(eax);
811 } else if (from->IsDoubleRegister()) {
812 __ movdbl(ToOperand(to), ToDoubleRegister(from));
813 } else if (to->IsDoubleRegister()) {
814 __ movdbl(ToDoubleRegister(to), ToOperand(from));
815 } else {
816 ASSERT(to->IsDoubleStackSlot() && from->IsDoubleStackSlot());
817 __ movdbl(xmm_scratch, ToOperand(from));
818 __ movdbl(ToOperand(to), xmm_scratch);
819 }
820 }
821
822 if (destroys_cpu_scratch) {
823 __ mov(cpu_scratch, Operand(ebp, -kPointerSize));
824 }
825 } 623 }
826 624
827 625
828 void LCodeGen::DoGap(LGap* gap) { 626 void LCodeGen::DoGap(LGap* gap) {
829 for (int i = LGap::FIRST_INNER_POSITION; 627 for (int i = LGap::FIRST_INNER_POSITION;
830 i <= LGap::LAST_INNER_POSITION; 628 i <= LGap::LAST_INNER_POSITION;
831 i++) { 629 i++) {
832 LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 630 LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i);
833 LParallelMove* move = gap->GetParallelMove(inner_pos); 631 LParallelMove* move = gap->GetParallelMove(inner_pos);
834 if (move != NULL) DoParallelMove(move); 632 if (move != NULL) DoParallelMove(move);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 } 699 }
902 } 700 }
903 701
904 702
905 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 703 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
906 // Nothing to do. 704 // Nothing to do.
907 } 705 }
908 706
909 707
910 void LCodeGen::DoModI(LModI* instr) { 708 void LCodeGen::DoModI(LModI* instr) {
911 LOperand* right = instr->right(); 709 LOperand* right = instr->InputAt(1);
912 ASSERT(ToRegister(instr->result()).is(edx)); 710 ASSERT(ToRegister(instr->result()).is(edx));
913 ASSERT(ToRegister(instr->left()).is(eax)); 711 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
914 ASSERT(!ToRegister(instr->right()).is(eax)); 712 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
915 ASSERT(!ToRegister(instr->right()).is(edx)); 713 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
916 714
917 Register right_reg = ToRegister(right); 715 Register right_reg = ToRegister(right);
918 716
919 // Check for x % 0. 717 // Check for x % 0.
920 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 718 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
921 __ test(right_reg, ToOperand(right)); 719 __ test(right_reg, ToOperand(right));
922 DeoptimizeIf(zero, instr->environment()); 720 DeoptimizeIf(zero, instr->environment());
923 } 721 }
924 722
925 // Sign extend to edx. 723 // Sign extend to edx.
(...skipping 15 matching lines...) Expand all
941 __ bind(&positive_left); 739 __ bind(&positive_left);
942 __ idiv(right_reg); 740 __ idiv(right_reg);
943 __ bind(&done); 741 __ bind(&done);
944 } else { 742 } else {
945 __ idiv(right_reg); 743 __ idiv(right_reg);
946 } 744 }
947 } 745 }
948 746
949 747
950 void LCodeGen::DoDivI(LDivI* instr) { 748 void LCodeGen::DoDivI(LDivI* instr) {
951 LOperand* right = instr->right(); 749 LOperand* right = instr->InputAt(1);
952 ASSERT(ToRegister(instr->result()).is(eax)); 750 ASSERT(ToRegister(instr->result()).is(eax));
953 ASSERT(ToRegister(instr->left()).is(eax)); 751 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
954 ASSERT(!ToRegister(instr->right()).is(eax)); 752 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
955 ASSERT(!ToRegister(instr->right()).is(edx)); 753 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
956 754
957 Register left_reg = eax; 755 Register left_reg = eax;
958 756
959 // Check for x / 0. 757 // Check for x / 0.
960 Register right_reg = ToRegister(right); 758 Register right_reg = ToRegister(right);
961 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 759 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
962 __ test(right_reg, ToOperand(right)); 760 __ test(right_reg, ToOperand(right));
963 DeoptimizeIf(zero, instr->environment()); 761 DeoptimizeIf(zero, instr->environment());
964 } 762 }
965 763
(...skipping 21 matching lines...) Expand all
987 __ cdq(); 785 __ cdq();
988 __ idiv(right_reg); 786 __ idiv(right_reg);
989 787
990 // Deoptimize if remainder is not 0. 788 // Deoptimize if remainder is not 0.
991 __ test(edx, Operand(edx)); 789 __ test(edx, Operand(edx));
992 DeoptimizeIf(not_zero, instr->environment()); 790 DeoptimizeIf(not_zero, instr->environment());
993 } 791 }
994 792
995 793
996 void LCodeGen::DoMulI(LMulI* instr) { 794 void LCodeGen::DoMulI(LMulI* instr) {
997 Register left = ToRegister(instr->left()); 795 Register left = ToRegister(instr->InputAt(0));
998 LOperand* right = instr->right(); 796 LOperand* right = instr->InputAt(1);
999 797
1000 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 798 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1001 __ mov(ToRegister(instr->temp()), left); 799 __ mov(ToRegister(instr->TempAt(0)), left);
1002 } 800 }
1003 801
1004 if (right->IsConstantOperand()) { 802 if (right->IsConstantOperand()) {
1005 __ imul(left, left, ToInteger32(LConstantOperand::cast(right))); 803 __ imul(left, left, ToInteger32(LConstantOperand::cast(right)));
1006 } else { 804 } else {
1007 __ imul(left, ToOperand(right)); 805 __ imul(left, ToOperand(right));
1008 } 806 }
1009 807
1010 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 808 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1011 DeoptimizeIf(overflow, instr->environment()); 809 DeoptimizeIf(overflow, instr->environment());
1012 } 810 }
1013 811
1014 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 812 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1015 // Bail out if the result is supposed to be negative zero. 813 // Bail out if the result is supposed to be negative zero.
1016 NearLabel done; 814 NearLabel done;
1017 __ test(left, Operand(left)); 815 __ test(left, Operand(left));
1018 __ j(not_zero, &done); 816 __ j(not_zero, &done);
1019 if (right->IsConstantOperand()) { 817 if (right->IsConstantOperand()) {
1020 if (ToInteger32(LConstantOperand::cast(right)) < 0) { 818 if (ToInteger32(LConstantOperand::cast(right)) < 0) {
1021 DeoptimizeIf(no_condition, instr->environment()); 819 DeoptimizeIf(no_condition, instr->environment());
1022 } 820 }
1023 } else { 821 } else {
1024 // Test the non-zero operand for negative sign. 822 // Test the non-zero operand for negative sign.
1025 __ or_(ToRegister(instr->temp()), ToOperand(right)); 823 __ or_(ToRegister(instr->TempAt(0)), ToOperand(right));
1026 DeoptimizeIf(sign, instr->environment()); 824 DeoptimizeIf(sign, instr->environment());
1027 } 825 }
1028 __ bind(&done); 826 __ bind(&done);
1029 } 827 }
1030 } 828 }
1031 829
1032 830
1033 void LCodeGen::DoBitI(LBitI* instr) { 831 void LCodeGen::DoBitI(LBitI* instr) {
1034 LOperand* left = instr->left(); 832 LOperand* left = instr->InputAt(0);
1035 LOperand* right = instr->right(); 833 LOperand* right = instr->InputAt(1);
1036 ASSERT(left->Equals(instr->result())); 834 ASSERT(left->Equals(instr->result()));
1037 ASSERT(left->IsRegister()); 835 ASSERT(left->IsRegister());
1038 836
1039 if (right->IsConstantOperand()) { 837 if (right->IsConstantOperand()) {
1040 int right_operand = ToInteger32(LConstantOperand::cast(right)); 838 int right_operand = ToInteger32(LConstantOperand::cast(right));
1041 switch (instr->op()) { 839 switch (instr->op()) {
1042 case Token::BIT_AND: 840 case Token::BIT_AND:
1043 __ and_(ToRegister(left), right_operand); 841 __ and_(ToRegister(left), right_operand);
1044 break; 842 break;
1045 case Token::BIT_OR: 843 case Token::BIT_OR:
(...skipping 19 matching lines...) Expand all
1065 break; 863 break;
1066 default: 864 default:
1067 UNREACHABLE(); 865 UNREACHABLE();
1068 break; 866 break;
1069 } 867 }
1070 } 868 }
1071 } 869 }
1072 870
1073 871
1074 void LCodeGen::DoShiftI(LShiftI* instr) { 872 void LCodeGen::DoShiftI(LShiftI* instr) {
1075 LOperand* left = instr->left(); 873 LOperand* left = instr->InputAt(0);
1076 LOperand* right = instr->right(); 874 LOperand* right = instr->InputAt(1);
1077 ASSERT(left->Equals(instr->result())); 875 ASSERT(left->Equals(instr->result()));
1078 ASSERT(left->IsRegister()); 876 ASSERT(left->IsRegister());
1079 if (right->IsRegister()) { 877 if (right->IsRegister()) {
1080 ASSERT(ToRegister(right).is(ecx)); 878 ASSERT(ToRegister(right).is(ecx));
1081 879
1082 switch (instr->op()) { 880 switch (instr->op()) {
1083 case Token::SAR: 881 case Token::SAR:
1084 __ sar_cl(ToRegister(left)); 882 __ sar_cl(ToRegister(left));
1085 break; 883 break;
1086 case Token::SHR: 884 case Token::SHR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 break; 919 break;
1122 default: 920 default:
1123 UNREACHABLE(); 921 UNREACHABLE();
1124 break; 922 break;
1125 } 923 }
1126 } 924 }
1127 } 925 }
1128 926
1129 927
1130 void LCodeGen::DoSubI(LSubI* instr) { 928 void LCodeGen::DoSubI(LSubI* instr) {
1131 LOperand* left = instr->left(); 929 LOperand* left = instr->InputAt(0);
1132 LOperand* right = instr->right(); 930 LOperand* right = instr->InputAt(1);
1133 ASSERT(left->Equals(instr->result())); 931 ASSERT(left->Equals(instr->result()));
1134 932
1135 if (right->IsConstantOperand()) { 933 if (right->IsConstantOperand()) {
1136 __ sub(ToOperand(left), ToImmediate(right)); 934 __ sub(ToOperand(left), ToImmediate(right));
1137 } else { 935 } else {
1138 __ sub(ToRegister(left), ToOperand(right)); 936 __ sub(ToRegister(left), ToOperand(right));
1139 } 937 }
1140 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 938 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1141 DeoptimizeIf(overflow, instr->environment()); 939 DeoptimizeIf(overflow, instr->environment());
1142 } 940 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 975
1178 976
1179 void LCodeGen::DoConstantT(LConstantT* instr) { 977 void LCodeGen::DoConstantT(LConstantT* instr) {
1180 ASSERT(instr->result()->IsRegister()); 978 ASSERT(instr->result()->IsRegister());
1181 __ Set(ToRegister(instr->result()), Immediate(instr->value())); 979 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1182 } 980 }
1183 981
1184 982
1185 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 983 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1186 Register result = ToRegister(instr->result()); 984 Register result = ToRegister(instr->result());
1187 Register array = ToRegister(instr->input()); 985 Register array = ToRegister(instr->InputAt(0));
1188 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); 986 __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
1189 } 987 }
1190 988
1191 989
1192 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 990 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
1193 Register result = ToRegister(instr->result()); 991 Register result = ToRegister(instr->result());
1194 Register array = ToRegister(instr->input()); 992 Register array = ToRegister(instr->InputAt(0));
1195 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); 993 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
1196 } 994 }
1197 995
1198 996
1199 void LCodeGen::DoValueOf(LValueOf* instr) { 997 void LCodeGen::DoValueOf(LValueOf* instr) {
1200 Register input = ToRegister(instr->input()); 998 Register input = ToRegister(instr->InputAt(0));
1201 Register result = ToRegister(instr->result()); 999 Register result = ToRegister(instr->result());
1202 Register map = ToRegister(instr->temporary()); 1000 Register map = ToRegister(instr->TempAt(0));
1203 ASSERT(input.is(result)); 1001 ASSERT(input.is(result));
1204 NearLabel done; 1002 NearLabel done;
1205 // If the object is a smi return the object. 1003 // If the object is a smi return the object.
1206 __ test(input, Immediate(kSmiTagMask)); 1004 __ test(input, Immediate(kSmiTagMask));
1207 __ j(zero, &done); 1005 __ j(zero, &done);
1208 1006
1209 // If the object is not a value type, return the object. 1007 // If the object is not a value type, return the object.
1210 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1008 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1211 __ j(not_equal, &done); 1009 __ j(not_equal, &done);
1212 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1010 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1213 1011
1214 __ bind(&done); 1012 __ bind(&done);
1215 } 1013 }
1216 1014
1217 1015
1218 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1016 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1219 LOperand* input = instr->input(); 1017 LOperand* input = instr->InputAt(0);
1220 ASSERT(input->Equals(instr->result())); 1018 ASSERT(input->Equals(instr->result()));
1221 __ not_(ToRegister(input)); 1019 __ not_(ToRegister(input));
1222 } 1020 }
1223 1021
1224 1022
1225 void LCodeGen::DoThrow(LThrow* instr) { 1023 void LCodeGen::DoThrow(LThrow* instr) {
1226 __ push(ToOperand(instr->input())); 1024 __ push(ToOperand(instr->InputAt(0)));
1227 CallRuntime(Runtime::kThrow, 1, instr); 1025 CallRuntime(Runtime::kThrow, 1, instr);
1228 1026
1229 if (FLAG_debug_code) { 1027 if (FLAG_debug_code) {
1230 Comment("Unreachable code."); 1028 Comment("Unreachable code.");
1231 __ int3(); 1029 __ int3();
1232 } 1030 }
1233 } 1031 }
1234 1032
1235 1033
1236 void LCodeGen::DoAddI(LAddI* instr) { 1034 void LCodeGen::DoAddI(LAddI* instr) {
1237 LOperand* left = instr->left(); 1035 LOperand* left = instr->InputAt(0);
1238 LOperand* right = instr->right(); 1036 LOperand* right = instr->InputAt(1);
1239 ASSERT(left->Equals(instr->result())); 1037 ASSERT(left->Equals(instr->result()));
1240 1038
1241 if (right->IsConstantOperand()) { 1039 if (right->IsConstantOperand()) {
1242 __ add(ToOperand(left), ToImmediate(right)); 1040 __ add(ToOperand(left), ToImmediate(right));
1243 } else { 1041 } else {
1244 __ add(ToRegister(left), ToOperand(right)); 1042 __ add(ToRegister(left), ToOperand(right));
1245 } 1043 }
1246 1044
1247 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1045 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1248 DeoptimizeIf(overflow, instr->environment()); 1046 DeoptimizeIf(overflow, instr->environment());
1249 } 1047 }
1250 } 1048 }
1251 1049
1252 1050
1253 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1051 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1254 LOperand* left = instr->left(); 1052 LOperand* left = instr->InputAt(0);
1255 LOperand* right = instr->right(); 1053 LOperand* right = instr->InputAt(1);
1256 // Modulo uses a fixed result register. 1054 // Modulo uses a fixed result register.
1257 ASSERT(instr->op() == Token::MOD || left->Equals(instr->result())); 1055 ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
1258 switch (instr->op()) { 1056 switch (instr->op()) {
1259 case Token::ADD: 1057 case Token::ADD:
1260 __ addsd(ToDoubleRegister(left), ToDoubleRegister(right)); 1058 __ addsd(ToDoubleRegister(left), ToDoubleRegister(right));
1261 break; 1059 break;
1262 case Token::SUB: 1060 case Token::SUB:
1263 __ subsd(ToDoubleRegister(left), ToDoubleRegister(right)); 1061 __ subsd(ToDoubleRegister(left), ToDoubleRegister(right));
1264 break; 1062 break;
1265 case Token::MUL: 1063 case Token::MUL:
(...skipping 18 matching lines...) Expand all
1284 break; 1082 break;
1285 } 1083 }
1286 default: 1084 default:
1287 UNREACHABLE(); 1085 UNREACHABLE();
1288 break; 1086 break;
1289 } 1087 }
1290 } 1088 }
1291 1089
1292 1090
1293 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1091 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1294 ASSERT(ToRegister(instr->left()).is(edx)); 1092 ASSERT(ToRegister(instr->InputAt(0)).is(edx));
1295 ASSERT(ToRegister(instr->right()).is(eax)); 1093 ASSERT(ToRegister(instr->InputAt(1)).is(eax));
1296 ASSERT(ToRegister(instr->result()).is(eax)); 1094 ASSERT(ToRegister(instr->result()).is(eax));
1297 1095
1298 TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE); 1096 TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
1299 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1097 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1300 } 1098 }
1301 1099
1302 1100
1303 int LCodeGen::GetNextEmittedBlock(int block) { 1101 int LCodeGen::GetNextEmittedBlock(int block) {
1304 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1102 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
1305 LLabel* label = chunk_->GetLabel(i); 1103 LLabel* label = chunk_->GetLabel(i);
(...skipping 20 matching lines...) Expand all
1326 } 1124 }
1327 } 1125 }
1328 1126
1329 1127
1330 void LCodeGen::DoBranch(LBranch* instr) { 1128 void LCodeGen::DoBranch(LBranch* instr) {
1331 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1129 int true_block = chunk_->LookupDestination(instr->true_block_id());
1332 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1130 int false_block = chunk_->LookupDestination(instr->false_block_id());
1333 1131
1334 Representation r = instr->hydrogen()->representation(); 1132 Representation r = instr->hydrogen()->representation();
1335 if (r.IsInteger32()) { 1133 if (r.IsInteger32()) {
1336 Register reg = ToRegister(instr->input()); 1134 Register reg = ToRegister(instr->InputAt(0));
1337 __ test(reg, Operand(reg)); 1135 __ test(reg, Operand(reg));
1338 EmitBranch(true_block, false_block, not_zero); 1136 EmitBranch(true_block, false_block, not_zero);
1339 } else if (r.IsDouble()) { 1137 } else if (r.IsDouble()) {
1340 XMMRegister reg = ToDoubleRegister(instr->input()); 1138 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1341 __ xorpd(xmm0, xmm0); 1139 __ xorpd(xmm0, xmm0);
1342 __ ucomisd(reg, xmm0); 1140 __ ucomisd(reg, xmm0);
1343 EmitBranch(true_block, false_block, not_equal); 1141 EmitBranch(true_block, false_block, not_equal);
1344 } else { 1142 } else {
1345 ASSERT(r.IsTagged()); 1143 ASSERT(r.IsTagged());
1346 Register reg = ToRegister(instr->input()); 1144 Register reg = ToRegister(instr->InputAt(0));
1347 if (instr->hydrogen()->type().IsBoolean()) { 1145 if (instr->hydrogen()->type().IsBoolean()) {
1348 __ cmp(reg, Factory::true_value()); 1146 __ cmp(reg, Factory::true_value());
1349 EmitBranch(true_block, false_block, equal); 1147 EmitBranch(true_block, false_block, equal);
1350 } else { 1148 } else {
1351 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1149 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1352 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1150 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1353 1151
1354 __ cmp(reg, Factory::undefined_value()); 1152 __ cmp(reg, Factory::undefined_value());
1355 __ j(equal, false_label); 1153 __ j(equal, false_label);
1356 __ cmp(reg, Factory::true_value()); 1154 __ cmp(reg, Factory::true_value());
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { 1262 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) {
1465 if (right->IsConstantOperand()) { 1263 if (right->IsConstantOperand()) {
1466 __ cmp(ToOperand(left), ToImmediate(right)); 1264 __ cmp(ToOperand(left), ToImmediate(right));
1467 } else { 1265 } else {
1468 __ cmp(ToRegister(left), ToOperand(right)); 1266 __ cmp(ToRegister(left), ToOperand(right));
1469 } 1267 }
1470 } 1268 }
1471 1269
1472 1270
1473 void LCodeGen::DoCmpID(LCmpID* instr) { 1271 void LCodeGen::DoCmpID(LCmpID* instr) {
1474 LOperand* left = instr->left(); 1272 LOperand* left = instr->InputAt(0);
1475 LOperand* right = instr->right(); 1273 LOperand* right = instr->InputAt(1);
1476 LOperand* result = instr->result(); 1274 LOperand* result = instr->result();
1477 1275
1478 NearLabel unordered; 1276 NearLabel unordered;
1479 if (instr->is_double()) { 1277 if (instr->is_double()) {
1480 // Don't base result on EFLAGS when a NaN is involved. Instead 1278 // Don't base result on EFLAGS when a NaN is involved. Instead
1481 // jump to the unordered case, which produces a false value. 1279 // jump to the unordered case, which produces a false value.
1482 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1280 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1483 __ j(parity_even, &unordered, not_taken); 1281 __ j(parity_even, &unordered, not_taken);
1484 } else { 1282 } else {
1485 EmitCmpI(left, right); 1283 EmitCmpI(left, right);
1486 } 1284 }
1487 1285
1488 NearLabel done; 1286 NearLabel done;
1489 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1287 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1490 __ mov(ToRegister(result), Handle<Object>(Heap::true_value())); 1288 __ mov(ToRegister(result), Handle<Object>(Heap::true_value()));
1491 __ j(cc, &done); 1289 __ j(cc, &done);
1492 1290
1493 __ bind(&unordered); 1291 __ bind(&unordered);
1494 __ mov(ToRegister(result), Handle<Object>(Heap::false_value())); 1292 __ mov(ToRegister(result), Handle<Object>(Heap::false_value()));
1495 __ bind(&done); 1293 __ bind(&done);
1496 } 1294 }
1497 1295
1498 1296
1499 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1297 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1500 LOperand* left = instr->left(); 1298 LOperand* left = instr->InputAt(0);
1501 LOperand* right = instr->right(); 1299 LOperand* right = instr->InputAt(1);
1502 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1300 int false_block = chunk_->LookupDestination(instr->false_block_id());
1503 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1301 int true_block = chunk_->LookupDestination(instr->true_block_id());
1504 1302
1505 if (instr->is_double()) { 1303 if (instr->is_double()) {
1506 // Don't base result on EFLAGS when a NaN is involved. Instead 1304 // Don't base result on EFLAGS when a NaN is involved. Instead
1507 // jump to the false block. 1305 // jump to the false block.
1508 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 1306 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
1509 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 1307 __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
1510 } else { 1308 } else {
1511 EmitCmpI(left, right); 1309 EmitCmpI(left, right);
1512 } 1310 }
1513 1311
1514 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1312 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1515 EmitBranch(true_block, false_block, cc); 1313 EmitBranch(true_block, false_block, cc);
1516 } 1314 }
1517 1315
1518 1316
1519 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { 1317 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
1520 Register left = ToRegister(instr->left()); 1318 Register left = ToRegister(instr->InputAt(0));
1521 Register right = ToRegister(instr->right()); 1319 Register right = ToRegister(instr->InputAt(1));
1522 Register result = ToRegister(instr->result()); 1320 Register result = ToRegister(instr->result());
1523 1321
1524 __ cmp(left, Operand(right)); 1322 __ cmp(left, Operand(right));
1525 __ mov(result, Handle<Object>(Heap::true_value())); 1323 __ mov(result, Handle<Object>(Heap::true_value()));
1526 NearLabel done; 1324 NearLabel done;
1527 __ j(equal, &done); 1325 __ j(equal, &done);
1528 __ mov(result, Handle<Object>(Heap::false_value())); 1326 __ mov(result, Handle<Object>(Heap::false_value()));
1529 __ bind(&done); 1327 __ bind(&done);
1530 } 1328 }
1531 1329
1532 1330
1533 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { 1331 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
1534 Register left = ToRegister(instr->left()); 1332 Register left = ToRegister(instr->InputAt(0));
1535 Register right = ToRegister(instr->right()); 1333 Register right = ToRegister(instr->InputAt(1));
1536 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1334 int false_block = chunk_->LookupDestination(instr->false_block_id());
1537 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1335 int true_block = chunk_->LookupDestination(instr->true_block_id());
1538 1336
1539 __ cmp(left, Operand(right)); 1337 __ cmp(left, Operand(right));
1540 EmitBranch(true_block, false_block, equal); 1338 EmitBranch(true_block, false_block, equal);
1541 } 1339 }
1542 1340
1543 1341
1544 void LCodeGen::DoIsNull(LIsNull* instr) { 1342 void LCodeGen::DoIsNull(LIsNull* instr) {
1545 Register reg = ToRegister(instr->input()); 1343 Register reg = ToRegister(instr->InputAt(0));
1546 Register result = ToRegister(instr->result()); 1344 Register result = ToRegister(instr->result());
1547 1345
1548 // TODO(fsc): If the expression is known to be a smi, then it's 1346 // TODO(fsc): If the expression is known to be a smi, then it's
1549 // definitely not null. Materialize false. 1347 // definitely not null. Materialize false.
1550 1348
1551 __ cmp(reg, Factory::null_value()); 1349 __ cmp(reg, Factory::null_value());
1552 if (instr->is_strict()) { 1350 if (instr->is_strict()) {
1553 __ mov(result, Handle<Object>(Heap::true_value())); 1351 __ mov(result, Handle<Object>(Heap::true_value()));
1554 NearLabel done; 1352 NearLabel done;
1555 __ j(equal, &done); 1353 __ j(equal, &done);
(...skipping 17 matching lines...) Expand all
1573 __ mov(result, Handle<Object>(Heap::false_value())); 1371 __ mov(result, Handle<Object>(Heap::false_value()));
1574 __ jmp(&done); 1372 __ jmp(&done);
1575 __ bind(&true_value); 1373 __ bind(&true_value);
1576 __ mov(result, Handle<Object>(Heap::true_value())); 1374 __ mov(result, Handle<Object>(Heap::true_value()));
1577 __ bind(&done); 1375 __ bind(&done);
1578 } 1376 }
1579 } 1377 }
1580 1378
1581 1379
1582 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1380 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1583 Register reg = ToRegister(instr->input()); 1381 Register reg = ToRegister(instr->InputAt(0));
1584 1382
1585 // TODO(fsc): If the expression is known to be a smi, then it's 1383 // TODO(fsc): If the expression is known to be a smi, then it's
1586 // definitely not null. Jump to the false block. 1384 // definitely not null. Jump to the false block.
1587 1385
1588 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1386 int true_block = chunk_->LookupDestination(instr->true_block_id());
1589 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1387 int false_block = chunk_->LookupDestination(instr->false_block_id());
1590 1388
1591 __ cmp(reg, Factory::null_value()); 1389 __ cmp(reg, Factory::null_value());
1592 if (instr->is_strict()) { 1390 if (instr->is_strict()) {
1593 EmitBranch(true_block, false_block, equal); 1391 EmitBranch(true_block, false_block, equal);
1594 } else { 1392 } else {
1595 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1393 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1596 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1394 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1597 __ j(equal, true_label); 1395 __ j(equal, true_label);
1598 __ cmp(reg, Factory::undefined_value()); 1396 __ cmp(reg, Factory::undefined_value());
1599 __ j(equal, true_label); 1397 __ j(equal, true_label);
1600 __ test(reg, Immediate(kSmiTagMask)); 1398 __ test(reg, Immediate(kSmiTagMask));
1601 __ j(zero, false_label); 1399 __ j(zero, false_label);
1602 // Check for undetectable objects by looking in the bit field in 1400 // Check for undetectable objects by looking in the bit field in
1603 // the map. The object has already been smi checked. 1401 // the map. The object has already been smi checked.
1604 Register scratch = ToRegister(instr->temp()); 1402 Register scratch = ToRegister(instr->TempAt(0));
1605 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1403 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1606 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); 1404 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
1607 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); 1405 __ test(scratch, Immediate(1 << Map::kIsUndetectable));
1608 EmitBranch(true_block, false_block, not_zero); 1406 EmitBranch(true_block, false_block, not_zero);
1609 } 1407 }
1610 } 1408 }
1611 1409
1612 1410
1613 Condition LCodeGen::EmitIsObject(Register input, 1411 Condition LCodeGen::EmitIsObject(Register input,
1614 Register temp1, 1412 Register temp1,
(...skipping 18 matching lines...) Expand all
1633 1431
1634 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset)); 1432 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
1635 __ cmp(temp2, FIRST_JS_OBJECT_TYPE); 1433 __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
1636 __ j(below, is_not_object); 1434 __ j(below, is_not_object);
1637 __ cmp(temp2, LAST_JS_OBJECT_TYPE); 1435 __ cmp(temp2, LAST_JS_OBJECT_TYPE);
1638 return below_equal; 1436 return below_equal;
1639 } 1437 }
1640 1438
1641 1439
1642 void LCodeGen::DoIsObject(LIsObject* instr) { 1440 void LCodeGen::DoIsObject(LIsObject* instr) {
1643 Register reg = ToRegister(instr->input()); 1441 Register reg = ToRegister(instr->InputAt(0));
1644 Register result = ToRegister(instr->result()); 1442 Register result = ToRegister(instr->result());
1645 Register temp = ToRegister(instr->temp()); 1443 Register temp = ToRegister(instr->TempAt(0));
1646 Label is_false, is_true, done; 1444 Label is_false, is_true, done;
1647 1445
1648 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); 1446 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
1649 __ j(true_cond, &is_true); 1447 __ j(true_cond, &is_true);
1650 1448
1651 __ bind(&is_false); 1449 __ bind(&is_false);
1652 __ mov(result, Handle<Object>(Heap::false_value())); 1450 __ mov(result, Handle<Object>(Heap::false_value()));
1653 __ jmp(&done); 1451 __ jmp(&done);
1654 1452
1655 __ bind(&is_true); 1453 __ bind(&is_true);
1656 __ mov(result, Handle<Object>(Heap::true_value())); 1454 __ mov(result, Handle<Object>(Heap::true_value()));
1657 1455
1658 __ bind(&done); 1456 __ bind(&done);
1659 } 1457 }
1660 1458
1661 1459
1662 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1460 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1663 Register reg = ToRegister(instr->input()); 1461 Register reg = ToRegister(instr->InputAt(0));
1664 Register temp = ToRegister(instr->temp()); 1462 Register temp = ToRegister(instr->TempAt(0));
1665 Register temp2 = ToRegister(instr->temp2()); 1463 Register temp2 = ToRegister(instr->TempAt(1));
1666 1464
1667 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1465 int true_block = chunk_->LookupDestination(instr->true_block_id());
1668 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1466 int false_block = chunk_->LookupDestination(instr->false_block_id());
1669 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1467 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1670 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1468 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1671 1469
1672 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); 1470 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label);
1673 1471
1674 EmitBranch(true_block, false_block, true_cond); 1472 EmitBranch(true_block, false_block, true_cond);
1675 } 1473 }
1676 1474
1677 1475
1678 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1476 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1679 Operand input = ToOperand(instr->input()); 1477 Operand input = ToOperand(instr->InputAt(0));
1680 Register result = ToRegister(instr->result()); 1478 Register result = ToRegister(instr->result());
1681 1479
1682 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1480 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1683 __ test(input, Immediate(kSmiTagMask)); 1481 __ test(input, Immediate(kSmiTagMask));
1684 __ mov(result, Handle<Object>(Heap::true_value())); 1482 __ mov(result, Handle<Object>(Heap::true_value()));
1685 NearLabel done; 1483 NearLabel done;
1686 __ j(zero, &done); 1484 __ j(zero, &done);
1687 __ mov(result, Handle<Object>(Heap::false_value())); 1485 __ mov(result, Handle<Object>(Heap::false_value()));
1688 __ bind(&done); 1486 __ bind(&done);
1689 } 1487 }
1690 1488
1691 1489
1692 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1490 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1693 Operand input = ToOperand(instr->input()); 1491 Operand input = ToOperand(instr->InputAt(0));
1694 1492
1695 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1493 int true_block = chunk_->LookupDestination(instr->true_block_id());
1696 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1494 int false_block = chunk_->LookupDestination(instr->false_block_id());
1697 1495
1698 __ test(input, Immediate(kSmiTagMask)); 1496 __ test(input, Immediate(kSmiTagMask));
1699 EmitBranch(true_block, false_block, zero); 1497 EmitBranch(true_block, false_block, zero);
1700 } 1498 }
1701 1499
1702 1500
1703 InstanceType LHasInstanceType::TestType() { 1501 static InstanceType TestType(HHasInstanceType* instr) {
1704 InstanceType from = hydrogen()->from(); 1502 InstanceType from = instr->from();
1705 InstanceType to = hydrogen()->to(); 1503 InstanceType to = instr->to();
1706 if (from == FIRST_TYPE) return to; 1504 if (from == FIRST_TYPE) return to;
1707 ASSERT(from == to || to == LAST_TYPE); 1505 ASSERT(from == to || to == LAST_TYPE);
1708 return from; 1506 return from;
1709 } 1507 }
1710 1508
1711 1509
1712 1510
1713 Condition LHasInstanceType::BranchCondition() { 1511 static Condition BranchCondition(HHasInstanceType* instr) {
1714 InstanceType from = hydrogen()->from(); 1512 InstanceType from = instr->from();
1715 InstanceType to = hydrogen()->to(); 1513 InstanceType to = instr->to();
1716 if (from == to) return equal; 1514 if (from == to) return equal;
1717 if (to == LAST_TYPE) return above_equal; 1515 if (to == LAST_TYPE) return above_equal;
1718 if (from == FIRST_TYPE) return below_equal; 1516 if (from == FIRST_TYPE) return below_equal;
1719 UNREACHABLE(); 1517 UNREACHABLE();
1720 return equal; 1518 return equal;
1721 } 1519 }
1722 1520
1723 1521
1724 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { 1522 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1725 Register input = ToRegister(instr->input()); 1523 Register input = ToRegister(instr->InputAt(0));
1726 Register result = ToRegister(instr->result()); 1524 Register result = ToRegister(instr->result());
1727 1525
1728 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1526 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1729 __ test(input, Immediate(kSmiTagMask)); 1527 __ test(input, Immediate(kSmiTagMask));
1730 NearLabel done, is_false; 1528 NearLabel done, is_false;
1731 __ j(zero, &is_false); 1529 __ j(zero, &is_false);
1732 __ CmpObjectType(input, instr->TestType(), result); 1530 __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1733 __ j(NegateCondition(instr->BranchCondition()), &is_false); 1531 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
1734 __ mov(result, Handle<Object>(Heap::true_value())); 1532 __ mov(result, Handle<Object>(Heap::true_value()));
1735 __ jmp(&done); 1533 __ jmp(&done);
1736 __ bind(&is_false); 1534 __ bind(&is_false);
1737 __ mov(result, Handle<Object>(Heap::false_value())); 1535 __ mov(result, Handle<Object>(Heap::false_value()));
1738 __ bind(&done); 1536 __ bind(&done);
1739 } 1537 }
1740 1538
1741 1539
1742 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1540 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1743 Register input = ToRegister(instr->input()); 1541 Register input = ToRegister(instr->InputAt(0));
1744 Register temp = ToRegister(instr->temp()); 1542 Register temp = ToRegister(instr->TempAt(0));
1745 1543
1746 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1544 int true_block = chunk_->LookupDestination(instr->true_block_id());
1747 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1545 int false_block = chunk_->LookupDestination(instr->false_block_id());
1748 1546
1749 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1547 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1750 1548
1751 __ test(input, Immediate(kSmiTagMask)); 1549 __ test(input, Immediate(kSmiTagMask));
1752 __ j(zero, false_label); 1550 __ j(zero, false_label);
1753 1551
1754 __ CmpObjectType(input, instr->TestType(), temp); 1552 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
1755 EmitBranch(true_block, false_block, instr->BranchCondition()); 1553 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1756 } 1554 }
1757 1555
1758 1556
1759 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { 1557 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1760 Register input = ToRegister(instr->input()); 1558 Register input = ToRegister(instr->InputAt(0));
1761 Register result = ToRegister(instr->result()); 1559 Register result = ToRegister(instr->result());
1762 1560
1763 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1561 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1764 __ mov(result, Handle<Object>(Heap::true_value())); 1562 __ mov(result, Handle<Object>(Heap::true_value()));
1765 __ test(FieldOperand(input, String::kHashFieldOffset), 1563 __ test(FieldOperand(input, String::kHashFieldOffset),
1766 Immediate(String::kContainsCachedArrayIndexMask)); 1564 Immediate(String::kContainsCachedArrayIndexMask));
1767 NearLabel done; 1565 NearLabel done;
1768 __ j(not_zero, &done); 1566 __ j(not_zero, &done);
1769 __ mov(result, Handle<Object>(Heap::false_value())); 1567 __ mov(result, Handle<Object>(Heap::false_value()));
1770 __ bind(&done); 1568 __ bind(&done);
1771 } 1569 }
1772 1570
1773 1571
1774 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1572 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1775 LHasCachedArrayIndexAndBranch* instr) { 1573 LHasCachedArrayIndexAndBranch* instr) {
1776 Register input = ToRegister(instr->input()); 1574 Register input = ToRegister(instr->InputAt(0));
1777 1575
1778 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1576 int true_block = chunk_->LookupDestination(instr->true_block_id());
1779 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1577 int false_block = chunk_->LookupDestination(instr->false_block_id());
1780 1578
1781 __ test(FieldOperand(input, String::kHashFieldOffset), 1579 __ test(FieldOperand(input, String::kHashFieldOffset),
1782 Immediate(String::kContainsCachedArrayIndexMask)); 1580 Immediate(String::kContainsCachedArrayIndexMask));
1783 EmitBranch(true_block, false_block, not_equal); 1581 EmitBranch(true_block, false_block, not_equal);
1784 } 1582 }
1785 1583
1786 1584
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 // booted. This routine isn't expected to work for random API-created 1633 // booted. This routine isn't expected to work for random API-created
1836 // classes and it doesn't have to because you can't access it with natives 1634 // classes and it doesn't have to because you can't access it with natives
1837 // syntax. Since both sides are symbols it is sufficient to use an identity 1635 // syntax. Since both sides are symbols it is sufficient to use an identity
1838 // comparison. 1636 // comparison.
1839 __ cmp(temp, class_name); 1637 __ cmp(temp, class_name);
1840 // End with the answer in the z flag. 1638 // End with the answer in the z flag.
1841 } 1639 }
1842 1640
1843 1641
1844 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1642 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1845 Register input = ToRegister(instr->input()); 1643 Register input = ToRegister(instr->InputAt(0));
1846 Register result = ToRegister(instr->result()); 1644 Register result = ToRegister(instr->result());
1847 ASSERT(input.is(result)); 1645 ASSERT(input.is(result));
1848 Register temp = ToRegister(instr->temporary()); 1646 Register temp = ToRegister(instr->TempAt(0));
1849 Handle<String> class_name = instr->hydrogen()->class_name(); 1647 Handle<String> class_name = instr->hydrogen()->class_name();
1850 NearLabel done; 1648 NearLabel done;
1851 Label is_true, is_false; 1649 Label is_true, is_false;
1852 1650
1853 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); 1651 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
1854 1652
1855 __ j(not_equal, &is_false); 1653 __ j(not_equal, &is_false);
1856 1654
1857 __ bind(&is_true); 1655 __ bind(&is_true);
1858 __ mov(result, Handle<Object>(Heap::true_value())); 1656 __ mov(result, Handle<Object>(Heap::true_value()));
1859 __ jmp(&done); 1657 __ jmp(&done);
1860 1658
1861 __ bind(&is_false); 1659 __ bind(&is_false);
1862 __ mov(result, Handle<Object>(Heap::false_value())); 1660 __ mov(result, Handle<Object>(Heap::false_value()));
1863 __ bind(&done); 1661 __ bind(&done);
1864 } 1662 }
1865 1663
1866 1664
1867 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1665 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1868 Register input = ToRegister(instr->input()); 1666 Register input = ToRegister(instr->InputAt(0));
1869 Register temp = ToRegister(instr->temporary()); 1667 Register temp = ToRegister(instr->TempAt(0));
1870 Register temp2 = ToRegister(instr->temporary2()); 1668 Register temp2 = ToRegister(instr->TempAt(1));
1871 if (input.is(temp)) { 1669 if (input.is(temp)) {
1872 // Swap. 1670 // Swap.
1873 Register swapper = temp; 1671 Register swapper = temp;
1874 temp = temp2; 1672 temp = temp2;
1875 temp2 = swapper; 1673 temp2 = swapper;
1876 } 1674 }
1877 Handle<String> class_name = instr->hydrogen()->class_name(); 1675 Handle<String> class_name = instr->hydrogen()->class_name();
1878 1676
1879 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1677 int true_block = chunk_->LookupDestination(instr->true_block_id());
1880 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1678 int false_block = chunk_->LookupDestination(instr->false_block_id());
1881 1679
1882 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1680 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1883 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1681 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1884 1682
1885 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 1683 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
1886 1684
1887 EmitBranch(true_block, false_block, equal); 1685 EmitBranch(true_block, false_block, equal);
1888 } 1686 }
1889 1687
1890 1688
1891 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1689 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1892 Register reg = ToRegister(instr->input()); 1690 Register reg = ToRegister(instr->InputAt(0));
1893 int true_block = instr->true_block_id(); 1691 int true_block = instr->true_block_id();
1894 int false_block = instr->false_block_id(); 1692 int false_block = instr->false_block_id();
1895 1693
1896 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 1694 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
1897 EmitBranch(true_block, false_block, equal); 1695 EmitBranch(true_block, false_block, equal);
1898 } 1696 }
1899 1697
1900 1698
1901 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1699 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1902 // Object and function are in fixed registers defined by the stub. 1700 // Object and function are in fixed registers defined by the stub.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 1737
1940 private: 1738 private:
1941 LInstanceOfKnownGlobal* instr_; 1739 LInstanceOfKnownGlobal* instr_;
1942 Label map_check_; 1740 Label map_check_;
1943 }; 1741 };
1944 1742
1945 DeferredInstanceOfKnownGlobal* deferred; 1743 DeferredInstanceOfKnownGlobal* deferred;
1946 deferred = new DeferredInstanceOfKnownGlobal(this, instr); 1744 deferred = new DeferredInstanceOfKnownGlobal(this, instr);
1947 1745
1948 Label done, false_result; 1746 Label done, false_result;
1949 Register object = ToRegister(instr->input()); 1747 Register object = ToRegister(instr->InputAt(0));
1950 Register temp = ToRegister(instr->temp()); 1748 Register temp = ToRegister(instr->TempAt(0));
1951 1749
1952 // A Smi is not instance of anything. 1750 // A Smi is not instance of anything.
1953 __ test(object, Immediate(kSmiTagMask)); 1751 __ test(object, Immediate(kSmiTagMask));
1954 __ j(zero, &false_result, not_taken); 1752 __ j(zero, &false_result, not_taken);
1955 1753
1956 // This is the inlined call site instanceof cache. The two occourences of the 1754 // This is the inlined call site instanceof cache. The two occourences of the
1957 // hole value will be patched to the last map/result pair generated by the 1755 // hole value will be patched to the last map/result pair generated by the
1958 // instanceof stub. 1756 // instanceof stub.
1959 NearLabel cache_miss; 1757 NearLabel cache_miss;
1960 Register map = ToRegister(instr->temp()); 1758 Register map = ToRegister(instr->TempAt(0));
1961 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 1759 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
1962 __ bind(deferred->map_check()); // Label for calculating code patching. 1760 __ bind(deferred->map_check()); // Label for calculating code patching.
1963 __ cmp(map, Factory::the_hole_value()); // Patched to cached map. 1761 __ cmp(map, Factory::the_hole_value()); // Patched to cached map.
1964 __ j(not_equal, &cache_miss, not_taken); 1762 __ j(not_equal, &cache_miss, not_taken);
1965 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false. 1763 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false.
1966 __ jmp(&done); 1764 __ jmp(&done);
1967 1765
1968 // The inlined call site cache did not match. Check null and string before 1766 // The inlined call site cache did not match. Check null and string before
1969 // calling the deferred code. 1767 // calling the deferred code.
1970 __ bind(&cache_miss); 1768 __ bind(&cache_miss);
(...skipping 27 matching lines...) Expand all
1998 flags | InstanceofStub::kArgsInRegisters); 1796 flags | InstanceofStub::kArgsInRegisters);
1999 flags = static_cast<InstanceofStub::Flags>( 1797 flags = static_cast<InstanceofStub::Flags>(
2000 flags | InstanceofStub::kCallSiteInlineCheck); 1798 flags | InstanceofStub::kCallSiteInlineCheck);
2001 flags = static_cast<InstanceofStub::Flags>( 1799 flags = static_cast<InstanceofStub::Flags>(
2002 flags | InstanceofStub::kReturnTrueFalseObject); 1800 flags | InstanceofStub::kReturnTrueFalseObject);
2003 InstanceofStub stub(flags); 1801 InstanceofStub stub(flags);
2004 1802
2005 // Get the temp register reserved by the instruction. This needs to be edi as 1803 // Get the temp register reserved by the instruction. This needs to be edi as
2006 // its slot of the pushing of safepoint registers is used to communicate the 1804 // its slot of the pushing of safepoint registers is used to communicate the
2007 // offset to the location of the map check. 1805 // offset to the location of the map check.
2008 Register temp = ToRegister(instr->temp()); 1806 Register temp = ToRegister(instr->TempAt(0));
2009 ASSERT(temp.is(edi)); 1807 ASSERT(temp.is(edi));
2010 __ mov(InstanceofStub::right(), Immediate(instr->function())); 1808 __ mov(InstanceofStub::right(), Immediate(instr->function()));
2011 static const int kAdditionalDelta = 13; 1809 static const int kAdditionalDelta = 13;
2012 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 1810 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2013 Label before_push_delta; 1811 Label before_push_delta;
2014 __ bind(&before_push_delta); 1812 __ bind(&before_push_delta);
2015 __ mov(temp, Immediate(delta)); 1813 __ mov(temp, Immediate(delta));
2016 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp); 1814 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp);
2017 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 1815 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2018 ASSERT_EQ(kAdditionalDelta, 1816 ASSERT_EQ(kAdditionalDelta,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 Register result = ToRegister(instr->result()); 1901 Register result = ToRegister(instr->result());
2104 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); 1902 __ mov(result, Operand::Cell(instr->hydrogen()->cell()));
2105 if (instr->hydrogen()->check_hole_value()) { 1903 if (instr->hydrogen()->check_hole_value()) {
2106 __ cmp(result, Factory::the_hole_value()); 1904 __ cmp(result, Factory::the_hole_value());
2107 DeoptimizeIf(equal, instr->environment()); 1905 DeoptimizeIf(equal, instr->environment());
2108 } 1906 }
2109 } 1907 }
2110 1908
2111 1909
2112 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 1910 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
2113 Register value = ToRegister(instr->input()); 1911 Register value = ToRegister(instr->InputAt(0));
2114 __ mov(Operand::Cell(instr->hydrogen()->cell()), value); 1912 __ mov(Operand::Cell(instr->hydrogen()->cell()), value);
2115 } 1913 }
2116 1914
2117 1915
2118 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 1916 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2119 // TODO(antonm): load a context with a separate instruction. 1917 // TODO(antonm): load a context with a separate instruction.
2120 Register result = ToRegister(instr->result()); 1918 Register result = ToRegister(instr->result());
2121 __ LoadContext(result, instr->context_chain_length()); 1919 __ LoadContext(result, instr->context_chain_length());
2122 __ mov(result, ContextOperand(result, instr->slot_index())); 1920 __ mov(result, ContextOperand(result, instr->slot_index()));
2123 } 1921 }
2124 1922
2125 1923
2126 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 1924 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2127 Register object = ToRegister(instr->input()); 1925 Register object = ToRegister(instr->InputAt(0));
2128 Register result = ToRegister(instr->result()); 1926 Register result = ToRegister(instr->result());
2129 if (instr->hydrogen()->is_in_object()) { 1927 if (instr->hydrogen()->is_in_object()) {
2130 __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); 1928 __ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
2131 } else { 1929 } else {
2132 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); 1930 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
2133 __ mov(result, FieldOperand(result, instr->hydrogen()->offset())); 1931 __ mov(result, FieldOperand(result, instr->hydrogen()->offset()));
2134 } 1932 }
2135 } 1933 }
2136 1934
2137 1935
2138 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 1936 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2139 ASSERT(ToRegister(instr->object()).is(eax)); 1937 ASSERT(ToRegister(instr->object()).is(eax));
2140 ASSERT(ToRegister(instr->result()).is(eax)); 1938 ASSERT(ToRegister(instr->result()).is(eax));
2141 1939
2142 __ mov(ecx, instr->name()); 1940 __ mov(ecx, instr->name());
2143 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1941 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
2144 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1942 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2145 } 1943 }
2146 1944
2147 1945
2148 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 1946 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2149 Register function = ToRegister(instr->function()); 1947 Register function = ToRegister(instr->function());
2150 Register temp = ToRegister(instr->temporary()); 1948 Register temp = ToRegister(instr->TempAt(0));
2151 Register result = ToRegister(instr->result()); 1949 Register result = ToRegister(instr->result());
2152 1950
2153 // Check that the function really is a function. 1951 // Check that the function really is a function.
2154 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 1952 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
2155 DeoptimizeIf(not_equal, instr->environment()); 1953 DeoptimizeIf(not_equal, instr->environment());
2156 1954
2157 // Check whether the function has an instance prototype. 1955 // Check whether the function has an instance prototype.
2158 NearLabel non_instance; 1956 NearLabel non_instance;
2159 __ test_b(FieldOperand(result, Map::kBitFieldOffset), 1957 __ test_b(FieldOperand(result, Map::kBitFieldOffset),
2160 1 << Map::kHasNonInstancePrototype); 1958 1 << Map::kHasNonInstancePrototype);
(...skipping 20 matching lines...) Expand all
2181 // in the function's map. 1979 // in the function's map.
2182 __ bind(&non_instance); 1980 __ bind(&non_instance);
2183 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 1981 __ mov(result, FieldOperand(result, Map::kConstructorOffset));
2184 1982
2185 // All done. 1983 // All done.
2186 __ bind(&done); 1984 __ bind(&done);
2187 } 1985 }
2188 1986
2189 1987
2190 void LCodeGen::DoLoadElements(LLoadElements* instr) { 1988 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2191 ASSERT(instr->result()->Equals(instr->input())); 1989 ASSERT(instr->result()->Equals(instr->InputAt(0)));
2192 Register reg = ToRegister(instr->input()); 1990 Register reg = ToRegister(instr->InputAt(0));
2193 __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset)); 1991 __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset));
2194 if (FLAG_debug_code) { 1992 if (FLAG_debug_code) {
2195 NearLabel done; 1993 NearLabel done;
2196 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1994 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2197 Immediate(Factory::fixed_array_map())); 1995 Immediate(Factory::fixed_array_map()));
2198 __ j(equal, &done); 1996 __ j(equal, &done);
2199 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1997 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2200 Immediate(Factory::fixed_cow_array_map())); 1998 Immediate(Factory::fixed_cow_array_map()));
2201 __ Check(equal, "Check for fast elements failed."); 1999 __ Check(equal, "Check for fast elements failed.");
2202 __ bind(&done); 2000 __ bind(&done);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 __ bind(&adapted); 2060 __ bind(&adapted);
2263 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2061 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2264 2062
2265 // Result is the frame pointer for the frame if not adapted and for the real 2063 // Result is the frame pointer for the frame if not adapted and for the real
2266 // frame below the adaptor frame if adapted. 2064 // frame below the adaptor frame if adapted.
2267 __ bind(&done); 2065 __ bind(&done);
2268 } 2066 }
2269 2067
2270 2068
2271 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2069 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2272 Operand elem = ToOperand(instr->input()); 2070 Operand elem = ToOperand(instr->InputAt(0));
2273 Register result = ToRegister(instr->result()); 2071 Register result = ToRegister(instr->result());
2274 2072
2275 NearLabel done; 2073 NearLabel done;
2276 2074
2277 // If no arguments adaptor frame the number of arguments is fixed. 2075 // If no arguments adaptor frame the number of arguments is fixed.
2278 __ cmp(ebp, elem); 2076 __ cmp(ebp, elem);
2279 __ mov(result, Immediate(scope()->num_parameters())); 2077 __ mov(result, Immediate(scope()->num_parameters()));
2280 __ j(equal, &done); 2078 __ j(equal, &done);
2281 2079
2282 // Arguments adaptor frame present. Get argument length from there. 2080 // Arguments adaptor frame present. Get argument length from there.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 ASSERT(receiver.is(eax)); 2134 ASSERT(receiver.is(eax));
2337 v8::internal::ParameterCount actual(eax); 2135 v8::internal::ParameterCount actual(eax);
2338 SafepointGenerator safepoint_generator(this, 2136 SafepointGenerator safepoint_generator(this,
2339 instr->pointer_map(), 2137 instr->pointer_map(),
2340 Safepoint::kNoDeoptimizationIndex); 2138 Safepoint::kNoDeoptimizationIndex);
2341 __ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator); 2139 __ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator);
2342 } 2140 }
2343 2141
2344 2142
2345 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2143 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2346 LOperand* argument = instr->input(); 2144 LOperand* argument = instr->InputAt(0);
2347 if (argument->IsConstantOperand()) { 2145 if (argument->IsConstantOperand()) {
2348 __ push(ToImmediate(argument)); 2146 __ push(ToImmediate(argument));
2349 } else { 2147 } else {
2350 __ push(ToOperand(argument)); 2148 __ push(ToOperand(argument));
2351 } 2149 }
2352 } 2150 }
2353 2151
2354 2152
2355 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 2153 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
2356 Register result = ToRegister(instr->result()); 2154 Register result = ToRegister(instr->result());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2402 2200
2403 2201
2404 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2202 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2405 ASSERT(ToRegister(instr->result()).is(eax)); 2203 ASSERT(ToRegister(instr->result()).is(eax));
2406 __ mov(edi, instr->function()); 2204 __ mov(edi, instr->function());
2407 CallKnownFunction(instr->function(), instr->arity(), instr); 2205 CallKnownFunction(instr->function(), instr->arity(), instr);
2408 } 2206 }
2409 2207
2410 2208
2411 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2209 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2412 Register input_reg = ToRegister(instr->input()); 2210 Register input_reg = ToRegister(instr->InputAt(0));
2413 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 2211 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
2414 Factory::heap_number_map()); 2212 Factory::heap_number_map());
2415 DeoptimizeIf(not_equal, instr->environment()); 2213 DeoptimizeIf(not_equal, instr->environment());
2416 2214
2417 Label done; 2215 Label done;
2418 Register tmp = input_reg.is(eax) ? ecx : eax; 2216 Register tmp = input_reg.is(eax) ? ecx : eax;
2419 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; 2217 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx;
2420 2218
2421 // Preserve the value of all registers. 2219 // Preserve the value of all registers.
2422 __ PushSafepointRegisters(); 2220 __ PushSafepointRegisters();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2267 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2470 LUnaryMathOperation* instr) 2268 LUnaryMathOperation* instr)
2471 : LDeferredCode(codegen), instr_(instr) { } 2269 : LDeferredCode(codegen), instr_(instr) { }
2472 virtual void Generate() { 2270 virtual void Generate() {
2473 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2271 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2474 } 2272 }
2475 private: 2273 private:
2476 LUnaryMathOperation* instr_; 2274 LUnaryMathOperation* instr_;
2477 }; 2275 };
2478 2276
2479 ASSERT(instr->input()->Equals(instr->result())); 2277 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2480 Representation r = instr->hydrogen()->value()->representation(); 2278 Representation r = instr->hydrogen()->value()->representation();
2481 2279
2482 if (r.IsDouble()) { 2280 if (r.IsDouble()) {
2483 XMMRegister scratch = xmm0; 2281 XMMRegister scratch = xmm0;
2484 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2282 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2485 __ pxor(scratch, scratch); 2283 __ pxor(scratch, scratch);
2486 __ subsd(scratch, input_reg); 2284 __ subsd(scratch, input_reg);
2487 __ pand(input_reg, scratch); 2285 __ pand(input_reg, scratch);
2488 } else if (r.IsInteger32()) { 2286 } else if (r.IsInteger32()) {
2489 Register input_reg = ToRegister(instr->input()); 2287 Register input_reg = ToRegister(instr->InputAt(0));
2490 __ test(input_reg, Operand(input_reg)); 2288 __ test(input_reg, Operand(input_reg));
2491 Label is_positive; 2289 Label is_positive;
2492 __ j(not_sign, &is_positive); 2290 __ j(not_sign, &is_positive);
2493 __ neg(input_reg); 2291 __ neg(input_reg);
2494 __ test(input_reg, Operand(input_reg)); 2292 __ test(input_reg, Operand(input_reg));
2495 DeoptimizeIf(negative, instr->environment()); 2293 DeoptimizeIf(negative, instr->environment());
2496 __ bind(&is_positive); 2294 __ bind(&is_positive);
2497 } else { // Tagged case. 2295 } else { // Tagged case.
2498 DeferredMathAbsTaggedHeapNumber* deferred = 2296 DeferredMathAbsTaggedHeapNumber* deferred =
2499 new DeferredMathAbsTaggedHeapNumber(this, instr); 2297 new DeferredMathAbsTaggedHeapNumber(this, instr);
2500 Label not_smi; 2298 Label not_smi;
2501 Register input_reg = ToRegister(instr->input()); 2299 Register input_reg = ToRegister(instr->InputAt(0));
2502 // Smi check. 2300 // Smi check.
2503 __ test(input_reg, Immediate(kSmiTagMask)); 2301 __ test(input_reg, Immediate(kSmiTagMask));
2504 __ j(not_zero, deferred->entry()); 2302 __ j(not_zero, deferred->entry());
2505 __ test(input_reg, Operand(input_reg)); 2303 __ test(input_reg, Operand(input_reg));
2506 Label is_positive; 2304 Label is_positive;
2507 __ j(not_sign, &is_positive); 2305 __ j(not_sign, &is_positive);
2508 __ neg(input_reg); 2306 __ neg(input_reg);
2509 2307
2510 __ test(input_reg, Operand(input_reg)); 2308 __ test(input_reg, Operand(input_reg));
2511 DeoptimizeIf(negative, instr->environment()); 2309 DeoptimizeIf(negative, instr->environment());
2512 2310
2513 __ bind(&is_positive); 2311 __ bind(&is_positive);
2514 __ bind(deferred->exit()); 2312 __ bind(deferred->exit());
2515 } 2313 }
2516 } 2314 }
2517 2315
2518 2316
2519 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2317 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2520 XMMRegister xmm_scratch = xmm0; 2318 XMMRegister xmm_scratch = xmm0;
2521 Register output_reg = ToRegister(instr->result()); 2319 Register output_reg = ToRegister(instr->result());
2522 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2320 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2523 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. 2321 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register.
2524 __ ucomisd(input_reg, xmm_scratch); 2322 __ ucomisd(input_reg, xmm_scratch);
2525 2323
2526 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2324 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2527 DeoptimizeIf(below_equal, instr->environment()); 2325 DeoptimizeIf(below_equal, instr->environment());
2528 } else { 2326 } else {
2529 DeoptimizeIf(below, instr->environment()); 2327 DeoptimizeIf(below, instr->environment());
2530 } 2328 }
2531 2329
2532 // Use truncating instruction (OK because input is positive). 2330 // Use truncating instruction (OK because input is positive).
2533 __ cvttsd2si(output_reg, Operand(input_reg)); 2331 __ cvttsd2si(output_reg, Operand(input_reg));
2534 2332
2535 // Overflow is signalled with minint. 2333 // Overflow is signalled with minint.
2536 __ cmp(output_reg, 0x80000000u); 2334 __ cmp(output_reg, 0x80000000u);
2537 DeoptimizeIf(equal, instr->environment()); 2335 DeoptimizeIf(equal, instr->environment());
2538 } 2336 }
2539 2337
2540 2338
2541 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2339 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2542 XMMRegister xmm_scratch = xmm0; 2340 XMMRegister xmm_scratch = xmm0;
2543 Register output_reg = ToRegister(instr->result()); 2341 Register output_reg = ToRegister(instr->result());
2544 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2342 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2545 2343
2546 // xmm_scratch = 0.5 2344 // xmm_scratch = 0.5
2547 ExternalReference one_half = ExternalReference::address_of_one_half(); 2345 ExternalReference one_half = ExternalReference::address_of_one_half();
2548 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 2346 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
2549 2347
2550 // input = input + 0.5 2348 // input = input + 0.5
2551 __ addsd(input_reg, xmm_scratch); 2349 __ addsd(input_reg, xmm_scratch);
2552 2350
2553 // We need to return -0 for the input range [-0.5, 0[, otherwise 2351 // We need to return -0 for the input range [-0.5, 0[, otherwise
2554 // compute Math.floor(value + 0.5). 2352 // compute Math.floor(value + 0.5).
(...skipping 12 matching lines...) Expand all
2567 // Use truncating instruction (OK because input is positive). 2365 // Use truncating instruction (OK because input is positive).
2568 __ cvttsd2si(output_reg, Operand(input_reg)); 2366 __ cvttsd2si(output_reg, Operand(input_reg));
2569 2367
2570 // Overflow is signalled with minint. 2368 // Overflow is signalled with minint.
2571 __ cmp(output_reg, 0x80000000u); 2369 __ cmp(output_reg, 0x80000000u);
2572 DeoptimizeIf(equal, instr->environment()); 2370 DeoptimizeIf(equal, instr->environment());
2573 } 2371 }
2574 2372
2575 2373
2576 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2374 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2577 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2375 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2578 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2376 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2579 __ sqrtsd(input_reg, input_reg); 2377 __ sqrtsd(input_reg, input_reg);
2580 } 2378 }
2581 2379
2582 2380
2583 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 2381 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2584 XMMRegister xmm_scratch = xmm0; 2382 XMMRegister xmm_scratch = xmm0;
2585 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2383 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2586 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2384 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2587 ExternalReference negative_infinity = 2385 ExternalReference negative_infinity =
2588 ExternalReference::address_of_negative_infinity(); 2386 ExternalReference::address_of_negative_infinity();
2589 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity)); 2387 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
2590 __ ucomisd(xmm_scratch, input_reg); 2388 __ ucomisd(xmm_scratch, input_reg);
2591 DeoptimizeIf(equal, instr->environment()); 2389 DeoptimizeIf(equal, instr->environment());
2592 __ sqrtsd(input_reg, input_reg); 2390 __ sqrtsd(input_reg, input_reg);
2593 } 2391 }
2594 2392
2595 2393
2596 void LCodeGen::DoPower(LPower* instr) { 2394 void LCodeGen::DoPower(LPower* instr) {
2597 LOperand* left = instr->left(); 2395 LOperand* left = instr->InputAt(0);
2598 LOperand* right = instr->right(); 2396 LOperand* right = instr->InputAt(1);
2599 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 2397 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2600 Representation exponent_type = instr->hydrogen()->right()->representation(); 2398 Representation exponent_type = instr->hydrogen()->right()->representation();
2601 if (exponent_type.IsDouble()) { 2399 if (exponent_type.IsDouble()) {
2602 // It is safe to use ebx directly since the instruction is marked 2400 // It is safe to use ebx directly since the instruction is marked
2603 // as a call. 2401 // as a call.
2604 __ PrepareCallCFunction(4, ebx); 2402 __ PrepareCallCFunction(4, ebx);
2605 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); 2403 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2606 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right)); 2404 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
2607 __ CallCFunction(ExternalReference::power_double_double_function(), 4); 2405 __ CallCFunction(ExternalReference::power_double_double_function(), 4);
2608 } else if (exponent_type.IsInteger32()) { 2406 } else if (exponent_type.IsInteger32()) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2701 break; 2499 break;
2702 2500
2703 default: 2501 default:
2704 UNREACHABLE(); 2502 UNREACHABLE();
2705 } 2503 }
2706 } 2504 }
2707 2505
2708 2506
2709 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 2507 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
2710 ASSERT(ToRegister(instr->result()).is(eax)); 2508 ASSERT(ToRegister(instr->result()).is(eax));
2509 ASSERT(ToRegister(instr->InputAt(0)).is(ecx));
2711 2510
2712 int arity = instr->arity(); 2511 int arity = instr->arity();
2713 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); 2512 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
2714 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2513 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2715 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2514 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2716 } 2515 }
2717 2516
2718 2517
2719 void LCodeGen::DoCallNamed(LCallNamed* instr) { 2518 void LCodeGen::DoCallNamed(LCallNamed* instr) {
2720 ASSERT(ToRegister(instr->result()).is(eax)); 2519 ASSERT(ToRegister(instr->result()).is(eax));
(...skipping 29 matching lines...) Expand all
2750 2549
2751 2550
2752 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 2551 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
2753 ASSERT(ToRegister(instr->result()).is(eax)); 2552 ASSERT(ToRegister(instr->result()).is(eax));
2754 __ mov(edi, instr->target()); 2553 __ mov(edi, instr->target());
2755 CallKnownFunction(instr->target(), instr->arity(), instr); 2554 CallKnownFunction(instr->target(), instr->arity(), instr);
2756 } 2555 }
2757 2556
2758 2557
2759 void LCodeGen::DoCallNew(LCallNew* instr) { 2558 void LCodeGen::DoCallNew(LCallNew* instr) {
2760 ASSERT(ToRegister(instr->input()).is(edi)); 2559 ASSERT(ToRegister(instr->InputAt(0)).is(edi));
2761 ASSERT(ToRegister(instr->result()).is(eax)); 2560 ASSERT(ToRegister(instr->result()).is(eax));
2762 2561
2763 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall)); 2562 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall));
2764 __ Set(eax, Immediate(instr->arity())); 2563 __ Set(eax, Immediate(instr->arity()));
2765 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); 2564 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
2766 } 2565 }
2767 2566
2768 2567
2769 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 2568 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
2770 CallRuntime(instr->function(), instr->arity(), instr); 2569 CallRuntime(instr->function(), instr->arity(), instr);
2771 } 2570 }
2772 2571
2773 2572
2774 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 2573 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
2775 Register object = ToRegister(instr->object()); 2574 Register object = ToRegister(instr->object());
2776 Register value = ToRegister(instr->value()); 2575 Register value = ToRegister(instr->value());
2777 int offset = instr->offset(); 2576 int offset = instr->offset();
2778 2577
2779 if (!instr->transition().is_null()) { 2578 if (!instr->transition().is_null()) {
2780 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 2579 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
2781 } 2580 }
2782 2581
2783 // Do the store. 2582 // Do the store.
2784 if (instr->is_in_object()) { 2583 if (instr->is_in_object()) {
2785 __ mov(FieldOperand(object, offset), value); 2584 __ mov(FieldOperand(object, offset), value);
2786 if (instr->needs_write_barrier()) { 2585 if (instr->needs_write_barrier()) {
2787 Register temp = ToRegister(instr->temp()); 2586 Register temp = ToRegister(instr->TempAt(0));
2788 // Update the write barrier for the object for in-object properties. 2587 // Update the write barrier for the object for in-object properties.
2789 __ RecordWrite(object, offset, value, temp); 2588 __ RecordWrite(object, offset, value, temp);
2790 } 2589 }
2791 } else { 2590 } else {
2792 Register temp = ToRegister(instr->temp()); 2591 Register temp = ToRegister(instr->TempAt(0));
2793 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 2592 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
2794 __ mov(FieldOperand(temp, offset), value); 2593 __ mov(FieldOperand(temp, offset), value);
2795 if (instr->needs_write_barrier()) { 2594 if (instr->needs_write_barrier()) {
2796 // Update the write barrier for the properties array. 2595 // Update the write barrier for the properties array.
2797 // object is used as a scratch register. 2596 // object is used as a scratch register.
2798 __ RecordWrite(temp, offset, value, object); 2597 __ RecordWrite(temp, offset, value, object);
2799 } 2598 }
2800 } 2599 }
2801 } 2600 }
2802 2601
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2846 ASSERT(ToRegister(instr->object()).is(edx)); 2645 ASSERT(ToRegister(instr->object()).is(edx));
2847 ASSERT(ToRegister(instr->key()).is(ecx)); 2646 ASSERT(ToRegister(instr->key()).is(ecx));
2848 ASSERT(ToRegister(instr->value()).is(eax)); 2647 ASSERT(ToRegister(instr->value()).is(eax));
2849 2648
2850 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 2649 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
2851 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2650 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2852 } 2651 }
2853 2652
2854 2653
2855 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2654 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
2856 LOperand* input = instr->input(); 2655 LOperand* input = instr->InputAt(0);
2857 ASSERT(input->IsRegister() || input->IsStackSlot()); 2656 ASSERT(input->IsRegister() || input->IsStackSlot());
2858 LOperand* output = instr->result(); 2657 LOperand* output = instr->result();
2859 ASSERT(output->IsDoubleRegister()); 2658 ASSERT(output->IsDoubleRegister());
2860 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 2659 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
2861 } 2660 }
2862 2661
2863 2662
2864 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 2663 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
2865 class DeferredNumberTagI: public LDeferredCode { 2664 class DeferredNumberTagI: public LDeferredCode {
2866 public: 2665 public:
2867 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 2666 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
2868 : LDeferredCode(codegen), instr_(instr) { } 2667 : LDeferredCode(codegen), instr_(instr) { }
2869 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 2668 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
2870 private: 2669 private:
2871 LNumberTagI* instr_; 2670 LNumberTagI* instr_;
2872 }; 2671 };
2873 2672
2874 LOperand* input = instr->input(); 2673 LOperand* input = instr->InputAt(0);
2875 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2674 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2876 Register reg = ToRegister(input); 2675 Register reg = ToRegister(input);
2877 2676
2878 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 2677 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
2879 __ SmiTag(reg); 2678 __ SmiTag(reg);
2880 __ j(overflow, deferred->entry()); 2679 __ j(overflow, deferred->entry());
2881 __ bind(deferred->exit()); 2680 __ bind(deferred->exit());
2882 } 2681 }
2883 2682
2884 2683
2885 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 2684 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
2886 Label slow; 2685 Label slow;
2887 Register reg = ToRegister(instr->input()); 2686 Register reg = ToRegister(instr->InputAt(0));
2888 Register tmp = reg.is(eax) ? ecx : eax; 2687 Register tmp = reg.is(eax) ? ecx : eax;
2889 2688
2890 // Preserve the value of all registers. 2689 // Preserve the value of all registers.
2891 __ PushSafepointRegisters(); 2690 __ PushSafepointRegisters();
2892 2691
2893 // There was overflow, so bits 30 and 31 of the original integer 2692 // There was overflow, so bits 30 and 31 of the original integer
2894 // disagree. Try to allocate a heap number in new space and store 2693 // disagree. Try to allocate a heap number in new space and store
2895 // the value in there. If that fails, call the runtime system. 2694 // the value in there. If that fails, call the runtime system.
2896 NearLabel done; 2695 NearLabel done;
2897 __ SmiUntag(reg); 2696 __ SmiUntag(reg);
(...skipping 29 matching lines...) Expand all
2927 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 2726 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
2928 class DeferredNumberTagD: public LDeferredCode { 2727 class DeferredNumberTagD: public LDeferredCode {
2929 public: 2728 public:
2930 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 2729 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
2931 : LDeferredCode(codegen), instr_(instr) { } 2730 : LDeferredCode(codegen), instr_(instr) { }
2932 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 2731 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
2933 private: 2732 private:
2934 LNumberTagD* instr_; 2733 LNumberTagD* instr_;
2935 }; 2734 };
2936 2735
2937 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2736 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2938 Register reg = ToRegister(instr->result()); 2737 Register reg = ToRegister(instr->result());
2939 Register tmp = ToRegister(instr->temp()); 2738 Register tmp = ToRegister(instr->TempAt(0));
2940 2739
2941 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 2740 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
2942 if (FLAG_inline_new) { 2741 if (FLAG_inline_new) {
2943 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 2742 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
2944 } else { 2743 } else {
2945 __ jmp(deferred->entry()); 2744 __ jmp(deferred->entry());
2946 } 2745 }
2947 __ bind(deferred->exit()); 2746 __ bind(deferred->exit());
2948 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 2747 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
2949 } 2748 }
2950 2749
2951 2750
2952 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 2751 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
2953 // TODO(3095996): Get rid of this. For now, we need to make the 2752 // TODO(3095996): Get rid of this. For now, we need to make the
2954 // result register contain a valid pointer because it is already 2753 // result register contain a valid pointer because it is already
2955 // contained in the register pointer map. 2754 // contained in the register pointer map.
2956 Register reg = ToRegister(instr->result()); 2755 Register reg = ToRegister(instr->result());
2957 __ Set(reg, Immediate(0)); 2756 __ Set(reg, Immediate(0));
2958 2757
2959 __ PushSafepointRegisters(); 2758 __ PushSafepointRegisters();
2960 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 2759 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
2961 RecordSafepointWithRegisters( 2760 RecordSafepointWithRegisters(
2962 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 2761 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
2963 __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), eax); 2762 __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), eax);
2964 __ PopSafepointRegisters(); 2763 __ PopSafepointRegisters();
2965 } 2764 }
2966 2765
2967 2766
2968 void LCodeGen::DoSmiTag(LSmiTag* instr) { 2767 void LCodeGen::DoSmiTag(LSmiTag* instr) {
2969 LOperand* input = instr->input(); 2768 LOperand* input = instr->InputAt(0);
2970 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2769 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2971 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 2770 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
2972 __ SmiTag(ToRegister(input)); 2771 __ SmiTag(ToRegister(input));
2973 } 2772 }
2974 2773
2975 2774
2976 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 2775 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
2977 LOperand* input = instr->input(); 2776 LOperand* input = instr->InputAt(0);
2978 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2777 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2979 if (instr->needs_check()) { 2778 if (instr->needs_check()) {
2980 __ test(ToRegister(input), Immediate(kSmiTagMask)); 2779 __ test(ToRegister(input), Immediate(kSmiTagMask));
2981 DeoptimizeIf(not_zero, instr->environment()); 2780 DeoptimizeIf(not_zero, instr->environment());
2982 } 2781 }
2983 __ SmiUntag(ToRegister(input)); 2782 __ SmiUntag(ToRegister(input));
2984 } 2783 }
2985 2784
2986 2785
2987 void LCodeGen::EmitNumberUntagD(Register input_reg, 2786 void LCodeGen::EmitNumberUntagD(Register input_reg,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 2826 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
3028 : LDeferredCode(codegen), instr_(instr) { } 2827 : LDeferredCode(codegen), instr_(instr) { }
3029 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 2828 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
3030 private: 2829 private:
3031 LTaggedToI* instr_; 2830 LTaggedToI* instr_;
3032 }; 2831 };
3033 2832
3034 2833
3035 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 2834 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
3036 NearLabel done, heap_number; 2835 NearLabel done, heap_number;
3037 Register input_reg = ToRegister(instr->input()); 2836 Register input_reg = ToRegister(instr->InputAt(0));
3038 2837
3039 // Heap number map check. 2838 // Heap number map check.
3040 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 2839 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3041 Factory::heap_number_map()); 2840 Factory::heap_number_map());
3042 2841
3043 if (instr->truncating()) { 2842 if (instr->truncating()) {
3044 __ j(equal, &heap_number); 2843 __ j(equal, &heap_number);
3045 // Check for undefined. Undefined is converted to zero for truncating 2844 // Check for undefined. Undefined is converted to zero for truncating
3046 // conversions. 2845 // conversions.
3047 __ cmp(input_reg, Factory::undefined_value()); 2846 __ cmp(input_reg, Factory::undefined_value());
(...skipping 22 matching lines...) Expand all
3070 2869
3071 // Reserve space for 64 bit answer. 2870 // Reserve space for 64 bit answer.
3072 __ bind(&convert); 2871 __ bind(&convert);
3073 __ sub(Operand(esp), Immediate(kDoubleSize)); 2872 __ sub(Operand(esp), Immediate(kDoubleSize));
3074 // Do conversion, which cannot fail because we checked the exponent. 2873 // Do conversion, which cannot fail because we checked the exponent.
3075 __ fisttp_d(Operand(esp, 0)); 2874 __ fisttp_d(Operand(esp, 0));
3076 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 2875 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
3077 __ add(Operand(esp), Immediate(kDoubleSize)); 2876 __ add(Operand(esp), Immediate(kDoubleSize));
3078 } else { 2877 } else {
3079 NearLabel deopt; 2878 NearLabel deopt;
3080 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 2879 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
3081 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2880 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3082 __ cvttsd2si(input_reg, Operand(xmm0)); 2881 __ cvttsd2si(input_reg, Operand(xmm0));
3083 __ cmp(input_reg, 0x80000000u); 2882 __ cmp(input_reg, 0x80000000u);
3084 __ j(not_equal, &done); 2883 __ j(not_equal, &done);
3085 // Check if the input was 0x8000000 (kMinInt). 2884 // Check if the input was 0x8000000 (kMinInt).
3086 // If no, then we got an overflow and we deoptimize. 2885 // If no, then we got an overflow and we deoptimize.
3087 ExternalReference min_int = ExternalReference::address_of_min_int(); 2886 ExternalReference min_int = ExternalReference::address_of_min_int();
3088 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 2887 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
3089 __ ucomisd(xmm_temp, xmm0); 2888 __ ucomisd(xmm_temp, xmm0);
3090 DeoptimizeIf(not_equal, instr->environment()); 2889 DeoptimizeIf(not_equal, instr->environment());
3091 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2890 DeoptimizeIf(parity_even, instr->environment()); // NaN.
3092 } 2891 }
3093 } else { 2892 } else {
3094 // Deoptimize if we don't have a heap number. 2893 // Deoptimize if we don't have a heap number.
3095 DeoptimizeIf(not_equal, instr->environment()); 2894 DeoptimizeIf(not_equal, instr->environment());
3096 2895
3097 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 2896 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
3098 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2897 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
3099 __ cvttsd2si(input_reg, Operand(xmm0)); 2898 __ cvttsd2si(input_reg, Operand(xmm0));
3100 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 2899 __ cvtsi2sd(xmm_temp, Operand(input_reg));
3101 __ ucomisd(xmm0, xmm_temp); 2900 __ ucomisd(xmm0, xmm_temp);
3102 DeoptimizeIf(not_equal, instr->environment()); 2901 DeoptimizeIf(not_equal, instr->environment());
3103 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2902 DeoptimizeIf(parity_even, instr->environment()); // NaN.
3104 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2903 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3105 __ test(input_reg, Operand(input_reg)); 2904 __ test(input_reg, Operand(input_reg));
3106 __ j(not_zero, &done); 2905 __ j(not_zero, &done);
3107 __ movmskpd(input_reg, xmm0); 2906 __ movmskpd(input_reg, xmm0);
3108 __ and_(input_reg, 1); 2907 __ and_(input_reg, 1);
3109 DeoptimizeIf(not_zero, instr->environment()); 2908 DeoptimizeIf(not_zero, instr->environment());
3110 } 2909 }
3111 } 2910 }
3112 __ bind(&done); 2911 __ bind(&done);
3113 } 2912 }
3114 2913
3115 2914
3116 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 2915 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
3117 LOperand* input = instr->input(); 2916 LOperand* input = instr->InputAt(0);
3118 ASSERT(input->IsRegister()); 2917 ASSERT(input->IsRegister());
3119 ASSERT(input->Equals(instr->result())); 2918 ASSERT(input->Equals(instr->result()));
3120 2919
3121 Register input_reg = ToRegister(input); 2920 Register input_reg = ToRegister(input);
3122 2921
3123 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); 2922 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
3124 2923
3125 // Smi check. 2924 // Smi check.
3126 __ test(input_reg, Immediate(kSmiTagMask)); 2925 __ test(input_reg, Immediate(kSmiTagMask));
3127 __ j(not_zero, deferred->entry()); 2926 __ j(not_zero, deferred->entry());
3128 2927
3129 // Smi to int32 conversion 2928 // Smi to int32 conversion
3130 __ SmiUntag(input_reg); // Untag smi. 2929 __ SmiUntag(input_reg); // Untag smi.
3131 2930
3132 __ bind(deferred->exit()); 2931 __ bind(deferred->exit());
3133 } 2932 }
3134 2933
3135 2934
3136 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 2935 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
3137 LOperand* input = instr->input(); 2936 LOperand* input = instr->InputAt(0);
3138 ASSERT(input->IsRegister()); 2937 ASSERT(input->IsRegister());
3139 LOperand* result = instr->result(); 2938 LOperand* result = instr->result();
3140 ASSERT(result->IsDoubleRegister()); 2939 ASSERT(result->IsDoubleRegister());
3141 2940
3142 Register input_reg = ToRegister(input); 2941 Register input_reg = ToRegister(input);
3143 XMMRegister result_reg = ToDoubleRegister(result); 2942 XMMRegister result_reg = ToDoubleRegister(result);
3144 2943
3145 EmitNumberUntagD(input_reg, result_reg, instr->environment()); 2944 EmitNumberUntagD(input_reg, result_reg, instr->environment());
3146 } 2945 }
3147 2946
3148 2947
3149 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 2948 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
3150 LOperand* input = instr->input(); 2949 LOperand* input = instr->InputAt(0);
3151 ASSERT(input->IsDoubleRegister()); 2950 ASSERT(input->IsDoubleRegister());
3152 LOperand* result = instr->result(); 2951 LOperand* result = instr->result();
3153 ASSERT(result->IsRegister()); 2952 ASSERT(result->IsRegister());
3154 2953
3155 XMMRegister input_reg = ToDoubleRegister(input); 2954 XMMRegister input_reg = ToDoubleRegister(input);
3156 Register result_reg = ToRegister(result); 2955 Register result_reg = ToRegister(result);
3157 2956
3158 if (instr->truncating()) { 2957 if (instr->truncating()) {
3159 // Performs a truncating conversion of a floating point number as used by 2958 // Performs a truncating conversion of a floating point number as used by
3160 // the JS bitwise operations. 2959 // the JS bitwise operations.
(...skipping 17 matching lines...) Expand all
3178 DeoptimizeIf(no_condition, instr->environment()); 2977 DeoptimizeIf(no_condition, instr->environment());
3179 __ bind(&convert); 2978 __ bind(&convert);
3180 // Do conversion, which cannot fail because we checked the exponent. 2979 // Do conversion, which cannot fail because we checked the exponent.
3181 __ fld_d(Operand(esp, 0)); 2980 __ fld_d(Operand(esp, 0));
3182 __ fisttp_d(Operand(esp, 0)); 2981 __ fisttp_d(Operand(esp, 0));
3183 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 2982 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
3184 __ add(Operand(esp), Immediate(kDoubleSize)); 2983 __ add(Operand(esp), Immediate(kDoubleSize));
3185 __ bind(&done); 2984 __ bind(&done);
3186 } else { 2985 } else {
3187 NearLabel done; 2986 NearLabel done;
3188 Register temp_reg = ToRegister(instr->temporary()); 2987 Register temp_reg = ToRegister(instr->TempAt(0));
3189 XMMRegister xmm_scratch = xmm0; 2988 XMMRegister xmm_scratch = xmm0;
3190 2989
3191 // If cvttsd2si succeeded, we're done. Otherwise, we attempt 2990 // If cvttsd2si succeeded, we're done. Otherwise, we attempt
3192 // manual conversion. 2991 // manual conversion.
3193 __ j(not_equal, &done); 2992 __ j(not_equal, &done);
3194 2993
3195 // Get high 32 bits of the input in result_reg and temp_reg. 2994 // Get high 32 bits of the input in result_reg and temp_reg.
3196 __ pshufd(xmm_scratch, input_reg, 1); 2995 __ pshufd(xmm_scratch, input_reg, 1);
3197 __ movd(Operand(temp_reg), xmm_scratch); 2996 __ movd(Operand(temp_reg), xmm_scratch);
3198 __ mov(result_reg, temp_reg); 2997 __ mov(result_reg, temp_reg);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3257 // deoptimize. 3056 // deoptimize.
3258 __ and_(result_reg, 1); 3057 __ and_(result_reg, 1);
3259 DeoptimizeIf(not_zero, instr->environment()); 3058 DeoptimizeIf(not_zero, instr->environment());
3260 } 3059 }
3261 __ bind(&done); 3060 __ bind(&done);
3262 } 3061 }
3263 } 3062 }
3264 3063
3265 3064
3266 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 3065 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
3267 LOperand* input = instr->input(); 3066 LOperand* input = instr->InputAt(0);
3268 ASSERT(input->IsRegister()); 3067 ASSERT(input->IsRegister());
3269 __ test(ToRegister(input), Immediate(kSmiTagMask)); 3068 __ test(ToRegister(input), Immediate(kSmiTagMask));
3270 DeoptimizeIf(instr->condition(), instr->environment()); 3069 DeoptimizeIf(instr->condition(), instr->environment());
3271 } 3070 }
3272 3071
3273 3072
3274 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3073 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3275 Register input = ToRegister(instr->input()); 3074 Register input = ToRegister(instr->InputAt(0));
3276 Register temp = ToRegister(instr->temp()); 3075 Register temp = ToRegister(instr->TempAt(0));
3277 InstanceType first = instr->hydrogen()->first(); 3076 InstanceType first = instr->hydrogen()->first();
3278 InstanceType last = instr->hydrogen()->last(); 3077 InstanceType last = instr->hydrogen()->last();
3279 3078
3280 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 3079 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
3281 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3080 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3282 static_cast<int8_t>(first)); 3081 static_cast<int8_t>(first));
3283 3082
3284 // If there is only one type in the interval check for equality. 3083 // If there is only one type in the interval check for equality.
3285 if (first == last) { 3084 if (first == last) {
3286 DeoptimizeIf(not_equal, instr->environment()); 3085 DeoptimizeIf(not_equal, instr->environment());
3287 } else { 3086 } else {
3288 DeoptimizeIf(below, instr->environment()); 3087 DeoptimizeIf(below, instr->environment());
3289 // Omit check for the last type. 3088 // Omit check for the last type.
3290 if (last != LAST_TYPE) { 3089 if (last != LAST_TYPE) {
3291 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3090 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3292 static_cast<int8_t>(last)); 3091 static_cast<int8_t>(last));
3293 DeoptimizeIf(above, instr->environment()); 3092 DeoptimizeIf(above, instr->environment());
3294 } 3093 }
3295 } 3094 }
3296 } 3095 }
3297 3096
3298 3097
3299 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 3098 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
3300 ASSERT(instr->input()->IsRegister()); 3099 ASSERT(instr->InputAt(0)->IsRegister());
3301 Register reg = ToRegister(instr->input()); 3100 Register reg = ToRegister(instr->InputAt(0));
3302 __ cmp(reg, instr->hydrogen()->target()); 3101 __ cmp(reg, instr->hydrogen()->target());
3303 DeoptimizeIf(not_equal, instr->environment()); 3102 DeoptimizeIf(not_equal, instr->environment());
3304 } 3103 }
3305 3104
3306 3105
3307 void LCodeGen::DoCheckMap(LCheckMap* instr) { 3106 void LCodeGen::DoCheckMap(LCheckMap* instr) {
3308 LOperand* input = instr->input(); 3107 LOperand* input = instr->InputAt(0);
3309 ASSERT(input->IsRegister()); 3108 ASSERT(input->IsRegister());
3310 Register reg = ToRegister(input); 3109 Register reg = ToRegister(input);
3311 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 3110 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
3312 instr->hydrogen()->map()); 3111 instr->hydrogen()->map());
3313 DeoptimizeIf(not_equal, instr->environment()); 3112 DeoptimizeIf(not_equal, instr->environment());
3314 } 3113 }
3315 3114
3316 3115
3317 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { 3116 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
3318 if (Heap::InNewSpace(*object)) { 3117 if (Heap::InNewSpace(*object)) {
3319 Handle<JSGlobalPropertyCell> cell = 3118 Handle<JSGlobalPropertyCell> cell =
3320 Factory::NewJSGlobalPropertyCell(object); 3119 Factory::NewJSGlobalPropertyCell(object);
3321 __ mov(result, Operand::Cell(cell)); 3120 __ mov(result, Operand::Cell(cell));
3322 } else { 3121 } else {
3323 __ mov(result, object); 3122 __ mov(result, object);
3324 } 3123 }
3325 } 3124 }
3326 3125
3327 3126
3328 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 3127 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
3329 Register reg = ToRegister(instr->temp()); 3128 Register reg = ToRegister(instr->TempAt(0));
3330 3129
3331 Handle<JSObject> holder = instr->holder(); 3130 Handle<JSObject> holder = instr->holder();
3332 Handle<JSObject> current_prototype = instr->prototype(); 3131 Handle<JSObject> current_prototype = instr->prototype();
3333 3132
3334 // Load prototype object. 3133 // Load prototype object.
3335 LoadHeapObject(reg, current_prototype); 3134 LoadHeapObject(reg, current_prototype);
3336 3135
3337 // Check prototype maps up to the holder. 3136 // Check prototype maps up to the holder.
3338 while (!current_prototype.is_identical_to(holder)) { 3137 while (!current_prototype.is_identical_to(holder)) {
3339 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 3138 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
3463 __ push(Immediate(shared_info)); 3262 __ push(Immediate(shared_info));
3464 __ push(Immediate(pretenure 3263 __ push(Immediate(pretenure
3465 ? Factory::true_value() 3264 ? Factory::true_value()
3466 : Factory::false_value())); 3265 : Factory::false_value()));
3467 CallRuntime(Runtime::kNewClosure, 3, instr); 3266 CallRuntime(Runtime::kNewClosure, 3, instr);
3468 } 3267 }
3469 } 3268 }
3470 3269
3471 3270
3472 void LCodeGen::DoTypeof(LTypeof* instr) { 3271 void LCodeGen::DoTypeof(LTypeof* instr) {
3473 LOperand* input = instr->input(); 3272 LOperand* input = instr->InputAt(0);
3474 if (input->IsConstantOperand()) { 3273 if (input->IsConstantOperand()) {
3475 __ push(ToImmediate(input)); 3274 __ push(ToImmediate(input));
3476 } else { 3275 } else {
3477 __ push(ToOperand(input)); 3276 __ push(ToOperand(input));
3478 } 3277 }
3479 CallRuntime(Runtime::kTypeof, 1, instr); 3278 CallRuntime(Runtime::kTypeof, 1, instr);
3480 } 3279 }
3481 3280
3482 3281
3483 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { 3282 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
3484 Register input = ToRegister(instr->input()); 3283 Register input = ToRegister(instr->InputAt(0));
3485 Register result = ToRegister(instr->result()); 3284 Register result = ToRegister(instr->result());
3486 Label true_label; 3285 Label true_label;
3487 Label false_label; 3286 Label false_label;
3488 NearLabel done; 3287 NearLabel done;
3489 3288
3490 Condition final_branch_condition = EmitTypeofIs(&true_label, 3289 Condition final_branch_condition = EmitTypeofIs(&true_label,
3491 &false_label, 3290 &false_label,
3492 input, 3291 input,
3493 instr->type_literal()); 3292 instr->type_literal());
3494 __ j(final_branch_condition, &true_label); 3293 __ j(final_branch_condition, &true_label);
3495 __ bind(&false_label); 3294 __ bind(&false_label);
3496 __ mov(result, Handle<Object>(Heap::false_value())); 3295 __ mov(result, Handle<Object>(Heap::false_value()));
3497 __ jmp(&done); 3296 __ jmp(&done);
3498 3297
3499 __ bind(&true_label); 3298 __ bind(&true_label);
3500 __ mov(result, Handle<Object>(Heap::true_value())); 3299 __ mov(result, Handle<Object>(Heap::true_value()));
3501 3300
3502 __ bind(&done); 3301 __ bind(&done);
3503 } 3302 }
3504 3303
3505 3304
3506 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 3305 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
3507 Register input = ToRegister(instr->input()); 3306 Register input = ToRegister(instr->InputAt(0));
3508 int true_block = chunk_->LookupDestination(instr->true_block_id()); 3307 int true_block = chunk_->LookupDestination(instr->true_block_id());
3509 int false_block = chunk_->LookupDestination(instr->false_block_id()); 3308 int false_block = chunk_->LookupDestination(instr->false_block_id());
3510 Label* true_label = chunk_->GetAssemblyLabel(true_block); 3309 Label* true_label = chunk_->GetAssemblyLabel(true_block);
3511 Label* false_label = chunk_->GetAssemblyLabel(false_block); 3310 Label* false_label = chunk_->GetAssemblyLabel(false_block);
3512 3311
3513 Condition final_branch_condition = EmitTypeofIs(true_label, 3312 Condition final_branch_condition = EmitTypeofIs(true_label,
3514 false_label, 3313 false_label,
3515 input, 3314 input,
3516 instr->type_literal()); 3315 instr->type_literal());
3517 3316
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3651 ASSERT(osr_pc_offset_ == -1); 3450 ASSERT(osr_pc_offset_ == -1);
3652 osr_pc_offset_ = masm()->pc_offset(); 3451 osr_pc_offset_ = masm()->pc_offset();
3653 } 3452 }
3654 3453
3655 3454
3656 #undef __ 3455 #undef __
3657 3456
3658 } } // namespace v8::internal 3457 } } // namespace v8::internal
3659 3458
3660 #endif // V8_TARGET_ARCH_IA32 3459 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698