| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 void CreateArrayComp::SetInputAt(intptr_t i, Value* value) { | 163 void CreateArrayComp::SetInputAt(intptr_t i, Value* value) { |
| 164 if (i == 0) { | 164 if (i == 0) { |
| 165 inputs_[0] = value; | 165 inputs_[0] = value; |
| 166 } else { | 166 } else { |
| 167 (*elements_)[i - 1] = value; | 167 (*elements_)[i - 1] = value; |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 intptr_t BranchInstr::InputCount() const { | 172 intptr_t BranchInstr::InputCount() const { |
| 173 return is_fused_with_comparison() ? fused_with_comparison_->InputCount() : 1; | 173 return 2; |
| 174 } | 174 } |
| 175 | 175 |
| 176 | 176 |
| 177 Value* BranchInstr::InputAt(intptr_t i) const { | 177 Value* BranchInstr::InputAt(intptr_t i) const { |
| 178 if (is_fused_with_comparison()) { | 178 if (i == 0) return left(); |
| 179 return fused_with_comparison_->InputAt(i); | 179 if (i == 1) return right(); |
| 180 } | |
| 181 if (i == 0) return value(); | |
| 182 UNREACHABLE(); | 180 UNREACHABLE(); |
| 183 return NULL; | 181 return NULL; |
| 184 } | 182 } |
| 185 | 183 |
| 186 | 184 |
| 187 void BranchInstr::SetInputAt(intptr_t i, Value* value) { | 185 void BranchInstr::SetInputAt(intptr_t i, Value* value) { |
| 188 ASSERT(!is_fused_with_comparison()); | |
| 189 if (i == 0) { | 186 if (i == 0) { |
| 190 value_ = value; | 187 left_ = value; |
| 191 return; | 188 } else if (i == 1) { |
| 189 right_ = value; |
| 190 } else { |
| 191 UNREACHABLE(); |
| 192 } | 192 } |
| 193 UNREACHABLE(); | |
| 194 } | 193 } |
| 195 | 194 |
| 196 | 195 |
| 197 intptr_t ParallelMoveInstr::InputCount() const { | 196 intptr_t ParallelMoveInstr::InputCount() const { |
| 198 UNREACHABLE(); | 197 UNREACHABLE(); |
| 199 return 0; | 198 return 0; |
| 200 } | 199 } |
| 201 | 200 |
| 202 | 201 |
| 203 Value* ParallelMoveInstr::InputAt(intptr_t i) const { | 202 Value* ParallelMoveInstr::InputAt(intptr_t i) const { |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 | 1029 |
| 1031 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1030 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1032 // We can fall through if the successor is the next block in the list. | 1031 // We can fall through if the successor is the next block in the list. |
| 1033 // Otherwise, we need a jump. | 1032 // Otherwise, we need a jump. |
| 1034 if (!compiler->IsNextBlock(successor())) { | 1033 if (!compiler->IsNextBlock(successor())) { |
| 1035 __ jmp(compiler->GetBlockLabel(successor())); | 1034 __ jmp(compiler->GetBlockLabel(successor())); |
| 1036 } | 1035 } |
| 1037 } | 1036 } |
| 1038 | 1037 |
| 1039 | 1038 |
| 1040 LocationSummary* BranchInstr::MakeLocationSummary() const { | |
| 1041 if (is_fused_with_comparison()) { | |
| 1042 return fused_with_comparison_->locs(); | |
| 1043 } else { | |
| 1044 const int kNumInputs = 1; | |
| 1045 const int kNumTemps = 0; | |
| 1046 LocationSummary* locs = new LocationSummary(kNumInputs, | |
| 1047 kNumTemps, | |
| 1048 LocationSummary::kNoCall); | |
| 1049 locs->set_in(0, Location::RequiresRegister()); | |
| 1050 return locs; | |
| 1051 } | |
| 1052 } | |
| 1053 | |
| 1054 | |
| 1055 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 1056 if (is_fused_with_comparison()) { | |
| 1057 fused_with_comparison_->EmitNativeCode(compiler); | |
| 1058 } else { | |
| 1059 Register value = locs()->in(0).reg(); | |
| 1060 __ CompareObject(value, compiler->bool_true()); | |
| 1061 EmitBranchOnCondition(compiler, EQUAL); | |
| 1062 } | |
| 1063 } | |
| 1064 | |
| 1065 | |
| 1066 static Condition NegateCondition(Condition condition) { | 1039 static Condition NegateCondition(Condition condition) { |
| 1067 switch (condition) { | 1040 switch (condition) { |
| 1068 case EQUAL: return NOT_EQUAL; | 1041 case EQUAL: return NOT_EQUAL; |
| 1069 case NOT_EQUAL: return EQUAL; | 1042 case NOT_EQUAL: return EQUAL; |
| 1070 case LESS: return GREATER_EQUAL; | 1043 case LESS: return GREATER_EQUAL; |
| 1071 case LESS_EQUAL: return GREATER; | 1044 case LESS_EQUAL: return GREATER; |
| 1072 case GREATER: return LESS_EQUAL; | 1045 case GREATER: return LESS_EQUAL; |
| 1073 case GREATER_EQUAL: return LESS; | 1046 case GREATER_EQUAL: return LESS; |
| 1074 case BELOW: return ABOVE_EQUAL; | 1047 case BELOW: return ABOVE_EQUAL; |
| 1075 case BELOW_EQUAL: return ABOVE; | 1048 case BELOW_EQUAL: return ABOVE; |
| 1076 case ABOVE: return BELOW_EQUAL; | 1049 case ABOVE: return BELOW_EQUAL; |
| 1077 case ABOVE_EQUAL: return BELOW; | 1050 case ABOVE_EQUAL: return BELOW; |
| 1078 default: | 1051 default: |
| 1079 OS::Print("Error %d\n", condition); | 1052 OS::Print("Error %d\n", condition); |
| 1080 UNIMPLEMENTED(); | 1053 UNIMPLEMENTED(); |
| 1081 return EQUAL; | 1054 return EQUAL; |
| 1082 } | 1055 } |
| 1083 } | 1056 } |
| 1084 | 1057 |
| 1085 | 1058 |
| 1086 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, | 1059 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 1087 Condition true_condition) { | 1060 Condition true_condition) { |
| 1088 if (is_negated()) { | |
| 1089 true_condition = NegateCondition(true_condition); | |
| 1090 } | |
| 1091 if (compiler->IsNextBlock(false_successor())) { | 1061 if (compiler->IsNextBlock(false_successor())) { |
| 1092 // If the next block is the false successor we will fall through to it. | 1062 // If the next block is the false successor we will fall through to it. |
| 1093 __ j(true_condition, compiler->GetBlockLabel(true_successor())); | 1063 __ j(true_condition, compiler->GetBlockLabel(true_successor())); |
| 1094 } else { | 1064 } else { |
| 1095 // If the next block is the true successor we negate comparison and fall | 1065 // If the next block is the true successor we negate comparison and fall |
| 1096 // through to it. | 1066 // through to it. |
| 1097 ASSERT(compiler->IsNextBlock(true_successor())); | 1067 ASSERT(compiler->IsNextBlock(true_successor())); |
| 1098 Condition false_condition = NegateCondition(true_condition); | 1068 Condition false_condition = NegateCondition(true_condition); |
| 1099 __ j(false_condition, compiler->GetBlockLabel(false_successor())); | 1069 __ j(false_condition, compiler->GetBlockLabel(false_successor())); |
| 1100 } | 1070 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1120 } | 1090 } |
| 1121 | 1091 |
| 1122 | 1092 |
| 1123 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1093 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1124 // Nothing to do. Context register were loaded by register allocator. | 1094 // Nothing to do. Context register were loaded by register allocator. |
| 1125 ASSERT(locs()->in(0).reg() == CTX); | 1095 ASSERT(locs()->in(0).reg() == CTX); |
| 1126 } | 1096 } |
| 1127 | 1097 |
| 1128 | 1098 |
| 1129 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 1099 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
| 1130 if (is_fused_with_branch()) { | 1100 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
| 1131 const intptr_t kNumInputs = 2; | |
| 1132 const intptr_t kNumTemps = 0; | |
| 1133 LocationSummary* locs = new LocationSummary(kNumInputs, | |
| 1134 kNumTemps, | |
| 1135 LocationSummary::kNoCall); | |
| 1136 locs->set_in(0, Location::RequiresRegister()); | |
| 1137 locs->set_in(1, Location::RequiresRegister()); | |
| 1138 return locs; | |
| 1139 } else { | |
| 1140 return LocationSummary::Make(2, Location::SameAsFirstInput()); | |
| 1141 } | |
| 1142 } | 1101 } |
| 1143 | 1102 |
| 1144 | 1103 |
| 1145 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1104 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1146 Register left = locs()->in(0).reg(); | 1105 Register left = locs()->in(0).reg(); |
| 1147 Register right = locs()->in(1).reg(); | 1106 Register right = locs()->in(1).reg(); |
| 1148 | 1107 |
| 1149 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 1108 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1150 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 1109 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 1151 __ CompareRegisters(left, right); | 1110 __ CompareRegisters(left, right); |
| 1152 | 1111 |
| 1153 if (is_fused_with_branch()) { | 1112 Register result = locs()->out().reg(); |
| 1154 fused_with_branch()->EmitBranchOnCondition(compiler, true_condition); | 1113 Label load_true, done; |
| 1155 } else { | 1114 __ j(true_condition, &load_true, Assembler::kNearJump); |
| 1156 Register result = locs()->out().reg(); | 1115 __ LoadObject(result, compiler->bool_false()); |
| 1157 Label load_true, done; | 1116 __ jmp(&done, Assembler::kNearJump); |
| 1158 __ j(true_condition, &load_true, Assembler::kNearJump); | 1117 __ Bind(&load_true); |
| 1159 __ LoadObject(result, compiler->bool_false()); | 1118 __ LoadObject(result, compiler->bool_true()); |
| 1160 __ jmp(&done, Assembler::kNearJump); | 1119 __ Bind(&done); |
| 1161 __ Bind(&load_true); | |
| 1162 __ LoadObject(result, compiler->bool_true()); | |
| 1163 __ Bind(&done); | |
| 1164 } | |
| 1165 } | 1120 } |
| 1166 | 1121 |
| 1167 | 1122 |
| 1168 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1123 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1169 ASSERT(VerifyCallComputation(this)); | 1124 ASSERT(VerifyCallComputation(this)); |
| 1170 // The arguments to the stub include the closure. The arguments | 1125 // The arguments to the stub include the closure. The arguments |
| 1171 // descriptor describes the closure's arguments (and so does not include | 1126 // descriptor describes the closure's arguments (and so does not include |
| 1172 // the closure). | 1127 // the closure). |
| 1173 Register temp_reg = locs()->temp(0).reg(); | 1128 Register temp_reg = locs()->temp(0).reg(); |
| 1174 int argument_count = ArgumentCount(); | 1129 int argument_count = ArgumentCount(); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1358 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1313 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1359 compiler->GenerateCall(token_pos(), try_index(), &label, | 1314 compiler->GenerateCall(token_pos(), try_index(), &label, |
| 1360 PcDescriptors::kOther); | 1315 PcDescriptors::kOther); |
| 1361 __ Drop(2); // Discard type arguments and receiver. | 1316 __ Drop(2); // Discard type arguments and receiver. |
| 1362 } | 1317 } |
| 1363 | 1318 |
| 1364 | 1319 |
| 1365 #undef __ | 1320 #undef __ |
| 1366 | 1321 |
| 1367 } // namespace dart | 1322 } // namespace dart |
| OLD | NEW |