OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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/globals.h" // Needed here to get TARGET_ARCH_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 193 |
194 if (is_power_of_two_kind) { | 194 if (is_power_of_two_kind) { |
195 const intptr_t shift = | 195 const intptr_t shift = |
196 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); | 196 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); |
197 __ LslImmediate(result, result, shift + kSmiTagSize); | 197 __ LslImmediate(result, result, shift + kSmiTagSize); |
198 } else { | 198 } else { |
199 __ sub(result, result, Operand(1)); | 199 __ sub(result, result, Operand(1)); |
200 const int64_t val = Smi::RawValue(true_value) - Smi::RawValue(false_value); | 200 const int64_t val = Smi::RawValue(true_value) - Smi::RawValue(false_value); |
201 __ AndImmediate(result, result, val); | 201 __ AndImmediate(result, result, val); |
202 if (false_value != 0) { | 202 if (false_value != 0) { |
203 __ AddImmediate(result, result, Smi::RawValue(false_value)); | 203 __ AddImmediate(result, Smi::RawValue(false_value)); |
204 } | 204 } |
205 } | 205 } |
206 } | 206 } |
207 | 207 |
208 | 208 |
209 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, | 209 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, |
210 bool opt) const { | 210 bool opt) const { |
211 const intptr_t kNumInputs = 1; | 211 const intptr_t kNumInputs = 1; |
212 const intptr_t kNumTemps = 0; | 212 const intptr_t kNumTemps = 0; |
213 LocationSummary* summary = new (zone) | 213 LocationSummary* summary = new (zone) |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 } | 865 } |
866 | 866 |
867 | 867 |
868 void OneByteStringFromCharCodeInstr::EmitNativeCode( | 868 void OneByteStringFromCharCodeInstr::EmitNativeCode( |
869 FlowGraphCompiler* compiler) { | 869 FlowGraphCompiler* compiler) { |
870 ASSERT(compiler->is_optimizing()); | 870 ASSERT(compiler->is_optimizing()); |
871 const Register char_code = locs()->in(0).reg(); | 871 const Register char_code = locs()->in(0).reg(); |
872 const Register result = locs()->out(0).reg(); | 872 const Register result = locs()->out(0).reg(); |
873 | 873 |
874 __ ldr(result, Address(THR, Thread::predefined_symbols_address_offset())); | 874 __ ldr(result, Address(THR, Thread::predefined_symbols_address_offset())); |
875 __ AddImmediate(result, result, | 875 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); |
876 Symbols::kNullCharCodeSymbolOffset * kWordSize); | |
877 __ SmiUntag(TMP, char_code); // Untag to use scaled address mode. | 876 __ SmiUntag(TMP, char_code); // Untag to use scaled address mode. |
878 __ ldr(result, Address(result, TMP, UXTX, Address::Scaled)); | 877 __ ldr(result, Address(result, TMP, UXTX, Address::Scaled)); |
879 } | 878 } |
880 | 879 |
881 | 880 |
882 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Zone* zone, | 881 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Zone* zone, |
883 bool opt) const { | 882 bool opt) const { |
884 const intptr_t kNumInputs = 1; | 883 const intptr_t kNumInputs = 1; |
885 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(), | 884 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(), |
886 LocationSummary::kNoCall); | 885 LocationSummary::kNoCall); |
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 while (current_offset < array_size) { | 2167 while (current_offset < array_size) { |
2169 __ str(R6, Address(R8, current_offset)); | 2168 __ str(R6, Address(R8, current_offset)); |
2170 current_offset += kWordSize; | 2169 current_offset += kWordSize; |
2171 } | 2170 } |
2172 } else { | 2171 } else { |
2173 Label end_loop, init_loop; | 2172 Label end_loop, init_loop; |
2174 __ Bind(&init_loop); | 2173 __ Bind(&init_loop); |
2175 __ CompareRegisters(R8, R3); | 2174 __ CompareRegisters(R8, R3); |
2176 __ b(&end_loop, CS); | 2175 __ b(&end_loop, CS); |
2177 __ str(R6, Address(R8)); | 2176 __ str(R6, Address(R8)); |
2178 __ AddImmediate(R8, R8, kWordSize); | 2177 __ AddImmediate(R8, kWordSize); |
2179 __ b(&init_loop); | 2178 __ b(&init_loop); |
2180 __ Bind(&end_loop); | 2179 __ Bind(&end_loop); |
2181 } | 2180 } |
2182 } | 2181 } |
2183 __ b(done); | 2182 __ b(done); |
2184 } | 2183 } |
2185 | 2184 |
2186 | 2185 |
2187 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2186 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2188 const Register kLengthReg = R2; | 2187 const Register kLengthReg = R2; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2416 __ CompareObject(function_type_args_reg, Object::null_object()); | 2415 __ CompareObject(function_type_args_reg, Object::null_object()); |
2417 __ b(&type_arguments_instantiated, EQ); | 2416 __ b(&type_arguments_instantiated, EQ); |
2418 __ Bind(&non_null_type_args); | 2417 __ Bind(&non_null_type_args); |
2419 } | 2418 } |
2420 | 2419 |
2421 // Lookup cache before calling runtime. | 2420 // Lookup cache before calling runtime. |
2422 // TODO(regis): Consider moving this into a shared stub to reduce | 2421 // TODO(regis): Consider moving this into a shared stub to reduce |
2423 // generated code size. | 2422 // generated code size. |
2424 __ LoadObject(R3, type_arguments()); | 2423 __ LoadObject(R3, type_arguments()); |
2425 __ LoadFieldFromOffset(R3, R3, TypeArguments::instantiations_offset()); | 2424 __ LoadFieldFromOffset(R3, R3, TypeArguments::instantiations_offset()); |
2426 __ AddImmediate(R3, R3, Array::data_offset() - kHeapObjectTag); | 2425 __ AddImmediate(R3, Array::data_offset() - kHeapObjectTag); |
2427 // The instantiations cache is initialized with Object::zero_array() and is | 2426 // The instantiations cache is initialized with Object::zero_array() and is |
2428 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2427 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
2429 Label loop, next, found, slow_case; | 2428 Label loop, next, found, slow_case; |
2430 __ Bind(&loop); | 2429 __ Bind(&loop); |
2431 __ LoadFromOffset(R2, R3, 0 * kWordSize); // Cached instantiator type args. | 2430 __ LoadFromOffset(R2, R3, 0 * kWordSize); // Cached instantiator type args. |
2432 __ CompareRegisters(R2, instantiator_type_args_reg); | 2431 __ CompareRegisters(R2, instantiator_type_args_reg); |
2433 __ b(&next, NE); | 2432 __ b(&next, NE); |
2434 __ LoadFromOffset(TMP, R3, 1 * kWordSize); // Cached function type args. | 2433 __ LoadFromOffset(TMP, R3, 1 * kWordSize); // Cached function type args. |
2435 __ CompareRegisters(TMP, function_type_args_reg); | 2434 __ CompareRegisters(TMP, function_type_args_reg); |
2436 __ b(&found, EQ); | 2435 __ b(&found, EQ); |
2437 __ Bind(&next); | 2436 __ Bind(&next); |
2438 __ AddImmediate(R3, R3, StubCode::kInstantiationSizeInWords * kWordSize); | 2437 __ AddImmediate(R3, StubCode::kInstantiationSizeInWords * kWordSize); |
2439 __ CompareImmediate(R2, Smi::RawValue(StubCode::kNoInstantiator)); | 2438 __ CompareImmediate(R2, Smi::RawValue(StubCode::kNoInstantiator)); |
2440 __ b(&loop, NE); | 2439 __ b(&loop, NE); |
2441 __ b(&slow_case); | 2440 __ b(&slow_case); |
2442 __ Bind(&found); | 2441 __ Bind(&found); |
2443 __ LoadFromOffset(result_reg, R3, 2 * kWordSize); // Cached instantiated ta. | 2442 __ LoadFromOffset(result_reg, R3, 2 * kWordSize); // Cached instantiated ta. |
2444 __ b(&type_arguments_instantiated); | 2443 __ b(&type_arguments_instantiated); |
2445 | 2444 |
2446 __ Bind(&slow_case); | 2445 __ Bind(&slow_case); |
2447 // Instantiate non-null type arguments. | 2446 // Instantiate non-null type arguments. |
2448 // A runtime call to instantiate the type arguments is required. | 2447 // A runtime call to instantiate the type arguments is required. |
(...skipping 3054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5503 __ b(deopt, cond); | 5502 __ b(deopt, cond); |
5504 } | 5503 } |
5505 | 5504 |
5506 | 5505 |
5507 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, | 5506 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, |
5508 intptr_t min, | 5507 intptr_t min, |
5509 intptr_t max, | 5508 intptr_t max, |
5510 intptr_t mask, | 5509 intptr_t mask, |
5511 Label* deopt) { | 5510 Label* deopt) { |
5512 Register biased_cid = locs()->temp(0).reg(); | 5511 Register biased_cid = locs()->temp(0).reg(); |
5513 __ AddImmediate(biased_cid, biased_cid, -min); | 5512 __ AddImmediate(biased_cid, -min); |
5514 __ CompareImmediate(biased_cid, max - min); | 5513 __ CompareImmediate(biased_cid, max - min); |
5515 __ b(deopt, HI); | 5514 __ b(deopt, HI); |
5516 | 5515 |
5517 Register bit_reg = locs()->temp(1).reg(); | 5516 Register bit_reg = locs()->temp(1).reg(); |
5518 __ LoadImmediate(bit_reg, 1); | 5517 __ LoadImmediate(bit_reg, 1); |
5519 __ lslv(bit_reg, bit_reg, biased_cid); | 5518 __ lslv(bit_reg, bit_reg, biased_cid); |
5520 __ TestImmediate(bit_reg, mask); | 5519 __ TestImmediate(bit_reg, mask); |
5521 __ b(deopt, EQ); | 5520 __ b(deopt, EQ); |
5522 } | 5521 } |
5523 | 5522 |
5524 | 5523 |
5525 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, | 5524 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, |
5526 int bias, | 5525 int bias, |
5527 intptr_t cid_start, | 5526 intptr_t cid_start, |
5528 intptr_t cid_end, | 5527 intptr_t cid_end, |
5529 bool is_last, | 5528 bool is_last, |
5530 Label* is_ok, | 5529 Label* is_ok, |
5531 Label* deopt, | 5530 Label* deopt, |
5532 bool use_near_jump) { | 5531 bool use_near_jump) { |
5533 Register biased_cid = locs()->temp(0).reg(); | 5532 Register biased_cid = locs()->temp(0).reg(); |
5534 Condition no_match, match; | 5533 Condition no_match, match; |
5535 if (cid_start == cid_end) { | 5534 if (cid_start == cid_end) { |
5536 __ CompareImmediate(biased_cid, cid_start - bias); | 5535 __ CompareImmediate(biased_cid, cid_start - bias); |
5537 no_match = NE; | 5536 no_match = NE; |
5538 match = EQ; | 5537 match = EQ; |
5539 } else { | 5538 } else { |
5540 // For class ID ranges use a subtract followed by an unsigned | 5539 // For class ID ranges use a subtract followed by an unsigned |
5541 // comparison to check both ends of the ranges with one comparison. | 5540 // comparison to check both ends of the ranges with one comparison. |
5542 __ AddImmediate(biased_cid, biased_cid, bias - cid_start); | 5541 __ AddImmediate(biased_cid, bias - cid_start); |
5543 bias = cid_start; | 5542 bias = cid_start; |
5544 __ CompareImmediate(biased_cid, cid_end - cid_start); | 5543 __ CompareImmediate(biased_cid, cid_end - cid_start); |
5545 no_match = HI; // Unsigned higher. | 5544 no_match = HI; // Unsigned higher. |
5546 match = LS; // Unsigned lower or same. | 5545 match = LS; // Unsigned lower or same. |
5547 } | 5546 } |
5548 if (is_last) { | 5547 if (is_last) { |
5549 __ b(deopt, no_match); | 5548 __ b(deopt, no_match); |
5550 } else { | 5549 } else { |
5551 __ b(is_ok, match); | 5550 __ b(is_ok, match); |
5552 } | 5551 } |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5927 | 5926 |
5928 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5927 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5929 Register target_address_reg = locs()->temp_slot(0)->reg(); | 5928 Register target_address_reg = locs()->temp_slot(0)->reg(); |
5930 | 5929 |
5931 // Load code entry point. | 5930 // Load code entry point. |
5932 const intptr_t entry_offset = __ CodeSize(); | 5931 const intptr_t entry_offset = __ CodeSize(); |
5933 if (Utils::IsInt(21, -entry_offset)) { | 5932 if (Utils::IsInt(21, -entry_offset)) { |
5934 __ adr(target_address_reg, Immediate(-entry_offset)); | 5933 __ adr(target_address_reg, Immediate(-entry_offset)); |
5935 } else { | 5934 } else { |
5936 __ adr(target_address_reg, Immediate(0)); | 5935 __ adr(target_address_reg, Immediate(0)); |
5937 __ AddImmediate(target_address_reg, target_address_reg, -entry_offset); | 5936 __ AddImmediate(target_address_reg, -entry_offset); |
5938 } | 5937 } |
5939 | 5938 |
5940 // Add the offset. | 5939 // Add the offset. |
5941 Register offset_reg = locs()->in(0).reg(); | 5940 Register offset_reg = locs()->in(0).reg(); |
5942 Operand offset_opr = (offset()->definition()->representation() == kTagged) | 5941 Operand offset_opr = (offset()->definition()->representation() == kTagged) |
5943 ? Operand(offset_reg, ASR, kSmiTagSize) | 5942 ? Operand(offset_reg, ASR, kSmiTagSize) |
5944 : Operand(offset_reg); | 5943 : Operand(offset_reg); |
5945 __ add(target_address_reg, target_address_reg, offset_opr); | 5944 __ add(target_address_reg, target_address_reg, offset_opr); |
5946 | 5945 |
5947 // Jump to the absolute address. | 5946 // Jump to the absolute address. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6091 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 6090 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
6092 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6091 kGrowRegExpStackRuntimeEntry, 1, locs()); |
6093 __ Drop(1); | 6092 __ Drop(1); |
6094 __ Pop(result); | 6093 __ Pop(result); |
6095 } | 6094 } |
6096 | 6095 |
6097 | 6096 |
6098 } // namespace dart | 6097 } // namespace dart |
6099 | 6098 |
6100 #endif // defined TARGET_ARCH_ARM64 | 6099 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |