| 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 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 ASSERT(exception()->IsUse()); | 979 ASSERT(exception()->IsUse()); |
| 981 ASSERT(stack_trace()->IsUse()); | 980 ASSERT(stack_trace()->IsUse()); |
| 982 compiler->GenerateCallRuntime(cid(), | 981 compiler->GenerateCallRuntime(cid(), |
| 983 token_pos(), | 982 token_pos(), |
| 984 try_index(), | 983 try_index(), |
| 985 kReThrowRuntimeEntry); | 984 kReThrowRuntimeEntry); |
| 986 __ int3(); | 985 __ int3(); |
| 987 } | 986 } |
| 988 | 987 |
| 989 | 988 |
| 990 LocationSummary* BranchInstr::MakeLocationSummary() const { | |
| 991 if (is_fused_with_comparison()) { | |
| 992 return fused_with_comparison_->locs(); | |
| 993 } else { | |
| 994 const int kNumInputs = 1; | |
| 995 const int kNumTemps = 0; | |
| 996 LocationSummary* locs = new LocationSummary(kNumInputs, | |
| 997 kNumTemps, | |
| 998 LocationSummary::kNoCall); | |
| 999 locs->set_in(0, Location::RequiresRegister()); | |
| 1000 return locs; | |
| 1001 } | |
| 1002 } | |
| 1003 | |
| 1004 | |
| 1005 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 1006 if (is_fused_with_comparison()) { | |
| 1007 fused_with_comparison_->EmitNativeCode(compiler); | |
| 1008 } else { | |
| 1009 Register value = locs()->in(0).reg(); | |
| 1010 __ CompareObject(value, compiler->bool_true()); | |
| 1011 EmitBranchOnCondition(compiler, EQUAL); | |
| 1012 } | |
| 1013 } | |
| 1014 | |
| 1015 | |
| 1016 static Condition NegateCondition(Condition condition) { | 989 static Condition NegateCondition(Condition condition) { |
| 1017 switch (condition) { | 990 switch (condition) { |
| 1018 case EQUAL: return NOT_EQUAL; | 991 case EQUAL: return NOT_EQUAL; |
| 1019 case NOT_EQUAL: return EQUAL; | 992 case NOT_EQUAL: return EQUAL; |
| 1020 case LESS: return GREATER_EQUAL; | 993 case LESS: return GREATER_EQUAL; |
| 1021 case LESS_EQUAL: return GREATER; | 994 case LESS_EQUAL: return GREATER; |
| 1022 case GREATER: return LESS_EQUAL; | 995 case GREATER: return LESS_EQUAL; |
| 1023 case GREATER_EQUAL: return LESS; | 996 case GREATER_EQUAL: return LESS; |
| 1024 case BELOW: return ABOVE_EQUAL; | 997 case BELOW: return ABOVE_EQUAL; |
| 1025 case BELOW_EQUAL: return ABOVE; | 998 case BELOW_EQUAL: return ABOVE; |
| 1026 case ABOVE: return BELOW_EQUAL; | 999 case ABOVE: return BELOW_EQUAL; |
| 1027 case ABOVE_EQUAL: return BELOW; | 1000 case ABOVE_EQUAL: return BELOW; |
| 1028 default: | 1001 default: |
| 1029 OS::Print("Error %d\n", condition); | 1002 OS::Print("Error %d\n", condition); |
| 1030 UNIMPLEMENTED(); | 1003 UNIMPLEMENTED(); |
| 1031 return EQUAL; | 1004 return EQUAL; |
| 1032 } | 1005 } |
| 1033 } | 1006 } |
| 1034 | 1007 |
| 1035 | 1008 |
| 1036 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, | 1009 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 1037 Condition true_condition) { | 1010 Condition true_condition) { |
| 1038 if (is_negated()) { | |
| 1039 true_condition = NegateCondition(true_condition); | |
| 1040 } | |
| 1041 if (compiler->IsNextBlock(false_successor())) { | 1011 if (compiler->IsNextBlock(false_successor())) { |
| 1042 // If the next block is the false successor we will fall through to it. | 1012 // If the next block is the false successor we will fall through to it. |
| 1043 __ j(true_condition, compiler->GetBlockLabel(true_successor())); | 1013 __ j(true_condition, compiler->GetBlockLabel(true_successor())); |
| 1044 } else { | 1014 } else { |
| 1045 // If the next block is the true successor we negate comparison and fall | 1015 // If the next block is the true successor we negate comparison and fall |
| 1046 // through to it. | 1016 // through to it. |
| 1047 ASSERT(compiler->IsNextBlock(true_successor())); | 1017 ASSERT(compiler->IsNextBlock(true_successor())); |
| 1048 Condition false_condition = NegateCondition(true_condition); | 1018 Condition false_condition = NegateCondition(true_condition); |
| 1049 __ j(false_condition, compiler->GetBlockLabel(false_successor())); | 1019 __ j(false_condition, compiler->GetBlockLabel(false_successor())); |
| 1050 } | 1020 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1070 } | 1040 } |
| 1071 | 1041 |
| 1072 | 1042 |
| 1073 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1043 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1074 // Nothing to do. Context register were loaded by register allocator. | 1044 // Nothing to do. Context register were loaded by register allocator. |
| 1075 ASSERT(locs()->in(0).reg() == CTX); | 1045 ASSERT(locs()->in(0).reg() == CTX); |
| 1076 } | 1046 } |
| 1077 | 1047 |
| 1078 | 1048 |
| 1079 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 1049 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
| 1080 if (is_fused_with_branch()) { | 1050 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
| 1081 const intptr_t kNumInputs = 2; | |
| 1082 const intptr_t kNumTemps = 0; | |
| 1083 LocationSummary* locs = new LocationSummary(kNumInputs, | |
| 1084 kNumTemps, | |
| 1085 LocationSummary::kNoCall); | |
| 1086 locs->set_in(0, Location::RequiresRegister()); | |
| 1087 locs->set_in(1, Location::RequiresRegister()); | |
| 1088 return locs; | |
| 1089 } else { | |
| 1090 return LocationSummary::Make(2, Location::SameAsFirstInput()); | |
| 1091 } | |
| 1092 } | 1051 } |
| 1093 | 1052 |
| 1094 | 1053 |
| 1095 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1054 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1096 Register left = locs()->in(0).reg(); | 1055 Register left = locs()->in(0).reg(); |
| 1097 Register right = locs()->in(1).reg(); | 1056 Register right = locs()->in(1).reg(); |
| 1098 | 1057 |
| 1099 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 1058 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1100 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 1059 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 1101 __ CompareRegisters(left, right); | 1060 __ CompareRegisters(left, right); |
| 1102 | 1061 |
| 1103 if (is_fused_with_branch()) { | 1062 Register result = locs()->out().reg(); |
| 1104 fused_with_branch()->EmitBranchOnCondition(compiler, true_condition); | 1063 Label load_true, done; |
| 1105 } else { | 1064 __ j(true_condition, &load_true, Assembler::kNearJump); |
| 1106 Register result = locs()->out().reg(); | 1065 __ LoadObject(result, compiler->bool_false()); |
| 1107 Label load_true, done; | 1066 __ jmp(&done, Assembler::kNearJump); |
| 1108 __ j(true_condition, &load_true, Assembler::kNearJump); | 1067 __ Bind(&load_true); |
| 1109 __ LoadObject(result, compiler->bool_false()); | 1068 __ LoadObject(result, compiler->bool_true()); |
| 1110 __ jmp(&done, Assembler::kNearJump); | 1069 __ Bind(&done); |
| 1111 __ Bind(&load_true); | |
| 1112 __ LoadObject(result, compiler->bool_true()); | |
| 1113 __ Bind(&done); | |
| 1114 } | |
| 1115 } | 1070 } |
| 1116 | 1071 |
| 1117 | 1072 |
| 1118 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1073 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1119 ASSERT(VerifyCallComputation(this)); | 1074 ASSERT(VerifyCallComputation(this)); |
| 1120 // The arguments to the stub include the closure. The arguments | 1075 // The arguments to the stub include the closure. The arguments |
| 1121 // descriptor describes the closure's arguments (and so does not include | 1076 // descriptor describes the closure's arguments (and so does not include |
| 1122 // the closure). | 1077 // the closure). |
| 1123 Register temp_reg = locs()->temp(0).reg(); | 1078 Register temp_reg = locs()->temp(0).reg(); |
| 1124 int argument_count = ArgumentCount(); | 1079 int argument_count = ArgumentCount(); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1263 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1309 compiler->GenerateCall(token_pos(), try_index(), &label, | 1264 compiler->GenerateCall(token_pos(), try_index(), &label, |
| 1310 PcDescriptors::kOther); | 1265 PcDescriptors::kOther); |
| 1311 __ Drop(2); // Discard type arguments and receiver. | 1266 __ Drop(2); // Discard type arguments and receiver. |
| 1312 } | 1267 } |
| 1313 | 1268 |
| 1314 | 1269 |
| 1315 #undef __ | 1270 #undef __ |
| 1316 | 1271 |
| 1317 } // namespace dart | 1272 } // namespace dart |
| OLD | NEW |