| OLD | NEW | 
|     1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file |     1 // Copyright (c) 2013, 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_ARM. |     5 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM. | 
|     6 #if defined(TARGET_ARCH_ARM) |     6 #if defined(TARGET_ARCH_ARM) | 
|     7  |     7  | 
|     8 #include "vm/intermediate_language.h" |     8 #include "vm/intermediate_language.h" | 
|     9  |     9  | 
|    10 #include "vm/cpu.h" |    10 #include "vm/cpu.h" | 
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   283       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |   283       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 
|   284   locs->set_out(0, Location::RequiresFpuRegister()); |   284   locs->set_out(0, Location::RequiresFpuRegister()); | 
|   285   locs->set_temp(0, Location::RequiresRegister()); |   285   locs->set_temp(0, Location::RequiresRegister()); | 
|   286   return locs; |   286   return locs; | 
|   287 } |   287 } | 
|   288  |   288  | 
|   289  |   289  | 
|   290 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |   290 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
|   291   // The register allocator drops constant definitions that have no uses. |   291   // The register allocator drops constant definitions that have no uses. | 
|   292   if (!locs()->out(0).IsInvalid()) { |   292   if (!locs()->out(0).IsInvalid()) { | 
|   293     if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { |   293     if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0) && | 
 |   294         TargetCPUFeatures::neon_supported()) { | 
|   294       const QRegister dst = locs()->out(0).fpu_reg(); |   295       const QRegister dst = locs()->out(0).fpu_reg(); | 
|   295       __ veorq(dst, dst, dst); |   296       __ veorq(dst, dst, dst); | 
|   296     } else { |   297     } else { | 
|   297       const DRegister dst = EvenDRegisterOf(locs()->out(0).fpu_reg()); |   298       const DRegister dst = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 
|   298       const Register temp = locs()->temp(0).reg(); |   299       const Register temp = locs()->temp(0).reg(); | 
|   299       __ LoadDImmediate(dst, Double::Cast(value()).value(), temp); |   300       __ LoadDImmediate(dst, Double::Cast(value()).value(), temp); | 
|   300     } |   301     } | 
|   301   } |   302   } | 
|   302 } |   303 } | 
|   303  |   304  | 
| (...skipping 1765 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2069       __ TryAllocate(compiler->double_class(), |  2070       __ TryAllocate(compiler->double_class(), | 
|  2070                      slow_path->entry_label(), |  2071                      slow_path->entry_label(), | 
|  2071                      temp, |  2072                      temp, | 
|  2072                      temp2); |  2073                      temp2); | 
|  2073       __ Bind(slow_path->exit_label()); |  2074       __ Bind(slow_path->exit_label()); | 
|  2074       __ MoveRegister(temp2, temp); |  2075       __ MoveRegister(temp2, temp); | 
|  2075       __ StoreIntoObject(instance_reg, |  2076       __ StoreIntoObject(instance_reg, | 
|  2076                          FieldAddress(instance_reg, offset_in_bytes_), |  2077                          FieldAddress(instance_reg, offset_in_bytes_), | 
|  2077                          temp2); |  2078                          temp2); | 
|  2078       __ Bind(©_double); |  2079       __ Bind(©_double); | 
|  2079       __ LoadDFromOffset(fpu_temp, |  2080       __ CopyDoubleField(temp, value_reg, TMP, temp2, fpu_temp); | 
|  2080                          value_reg, |  | 
|  2081                          Double::value_offset() - kHeapObjectTag); |  | 
|  2082       __ StoreDToOffset(fpu_temp, |  | 
|  2083                         temp, |  | 
|  2084                         Double::value_offset() - kHeapObjectTag); |  | 
|  2085       __ b(&skip_store); |  2081       __ b(&skip_store); | 
|  2086     } |  2082     } | 
|  2087  |  2083  | 
|  2088     { |  2084     { | 
|  2089       __ Bind(&store_float32x4); |  2085       __ Bind(&store_float32x4); | 
|  2090       Label copy_float32x4; |  2086       Label copy_float32x4; | 
|  2091       StoreInstanceFieldSlowPath* slow_path = |  2087       StoreInstanceFieldSlowPath* slow_path = | 
|  2092           new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); |  2088           new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); | 
|  2093       compiler->AddSlowPathCode(slow_path); |  2089       compiler->AddSlowPathCode(slow_path); | 
|  2094  |  2090  | 
|  2095       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); |  2091       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 
|  2096       __ CompareImmediate(temp, |  2092       __ CompareImmediate(temp, | 
|  2097                           reinterpret_cast<intptr_t>(Object::null())); |  2093                           reinterpret_cast<intptr_t>(Object::null())); | 
|  2098       __ b(©_float32x4, NE); |  2094       __ b(©_float32x4, NE); | 
|  2099  |  2095  | 
|  2100       __ TryAllocate(compiler->float32x4_class(), |  2096       __ TryAllocate(compiler->float32x4_class(), | 
|  2101                      slow_path->entry_label(), |  2097                      slow_path->entry_label(), | 
|  2102                      temp, |  2098                      temp, | 
|  2103                      temp2); |  2099                      temp2); | 
|  2104       __ Bind(slow_path->exit_label()); |  2100       __ Bind(slow_path->exit_label()); | 
|  2105       __ MoveRegister(temp2, temp); |  2101       __ MoveRegister(temp2, temp); | 
|  2106       __ StoreIntoObject(instance_reg, |  2102       __ StoreIntoObject(instance_reg, | 
|  2107                          FieldAddress(instance_reg, offset_in_bytes_), |  2103                          FieldAddress(instance_reg, offset_in_bytes_), | 
|  2108                          temp2); |  2104                          temp2); | 
|  2109       __ Bind(©_float32x4); |  2105       __ Bind(©_float32x4); | 
|  2110       __ LoadMultipleDFromOffset(fpu_temp, 2, value_reg, |  2106       __ CopyFloat32x4Field(temp, value_reg, TMP, temp2, fpu_temp); | 
|  2111           Float32x4::value_offset() - kHeapObjectTag); |  | 
|  2112       __ StoreMultipleDToOffset(fpu_temp, 2, temp, |  | 
|  2113           Float32x4::value_offset() - kHeapObjectTag); |  | 
|  2114       __ b(&skip_store); |  2107       __ b(&skip_store); | 
|  2115     } |  2108     } | 
|  2116  |  2109  | 
|  2117     { |  2110     { | 
|  2118       __ Bind(&store_float64x2); |  2111       __ Bind(&store_float64x2); | 
|  2119       Label copy_float64x2; |  2112       Label copy_float64x2; | 
|  2120       StoreInstanceFieldSlowPath* slow_path = |  2113       StoreInstanceFieldSlowPath* slow_path = | 
|  2121           new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); |  2114           new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); | 
|  2122       compiler->AddSlowPathCode(slow_path); |  2115       compiler->AddSlowPathCode(slow_path); | 
|  2123  |  2116  | 
|  2124       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); |  2117       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 
|  2125       __ CompareImmediate(temp, |  2118       __ CompareImmediate(temp, | 
|  2126                           reinterpret_cast<intptr_t>(Object::null())); |  2119                           reinterpret_cast<intptr_t>(Object::null())); | 
|  2127       __ b(©_float64x2, NE); |  2120       __ b(©_float64x2, NE); | 
|  2128  |  2121  | 
|  2129       __ TryAllocate(compiler->float64x2_class(), |  2122       __ TryAllocate(compiler->float64x2_class(), | 
|  2130                      slow_path->entry_label(), |  2123                      slow_path->entry_label(), | 
|  2131                      temp, |  2124                      temp, | 
|  2132                      temp2); |  2125                      temp2); | 
|  2133       __ Bind(slow_path->exit_label()); |  2126       __ Bind(slow_path->exit_label()); | 
|  2134       __ MoveRegister(temp2, temp); |  2127       __ MoveRegister(temp2, temp); | 
|  2135       __ StoreIntoObject(instance_reg, |  2128       __ StoreIntoObject(instance_reg, | 
|  2136                          FieldAddress(instance_reg, offset_in_bytes_), |  2129                          FieldAddress(instance_reg, offset_in_bytes_), | 
|  2137                          temp2); |  2130                          temp2); | 
|  2138       __ Bind(©_float64x2); |  2131       __ Bind(©_float64x2); | 
|  2139       __ LoadMultipleDFromOffset(fpu_temp, 2, value_reg, |  2132       __ CopyFloat64x2Field(temp, value_reg, TMP, temp2, fpu_temp); | 
|  2140           Float64x2::value_offset() - kHeapObjectTag); |  | 
|  2141       __ StoreMultipleDToOffset(fpu_temp, 2, temp, |  | 
|  2142           Float64x2::value_offset() - kHeapObjectTag); |  | 
|  2143       __ b(&skip_store); |  2133       __ b(&skip_store); | 
|  2144     } |  2134     } | 
|  2145  |  2135  | 
|  2146     __ Bind(&store_pointer); |  2136     __ Bind(&store_pointer); | 
|  2147   } |  2137   } | 
|  2148  |  2138  | 
|  2149   if (ShouldEmitStoreBarrier()) { |  2139   if (ShouldEmitStoreBarrier()) { | 
|  2150     Register value_reg = locs()->in(1).reg(); |  2140     Register value_reg = locs()->in(1).reg(); | 
|  2151     __ StoreIntoObject(instance_reg, |  2141     __ StoreIntoObject(instance_reg, | 
|  2152                        FieldAddress(instance_reg, offset_in_bytes_), |  2142                        FieldAddress(instance_reg, offset_in_bytes_), | 
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2474           : LocationSummary::kCallOnSlowPath); |  2464           : LocationSummary::kCallOnSlowPath); | 
|  2475  |  2465  | 
|  2476   locs->set_in(0, Location::RequiresRegister()); |  2466   locs->set_in(0, Location::RequiresRegister()); | 
|  2477  |  2467  | 
|  2478   if (IsUnboxedLoad() && opt) { |  2468   if (IsUnboxedLoad() && opt) { | 
|  2479     locs->AddTemp(Location::RequiresRegister()); |  2469     locs->AddTemp(Location::RequiresRegister()); | 
|  2480   } else if (IsPotentialUnboxedLoad()) { |  2470   } else if (IsPotentialUnboxedLoad()) { | 
|  2481     locs->AddTemp(opt ? Location::RequiresFpuRegister() |  2471     locs->AddTemp(opt ? Location::RequiresFpuRegister() | 
|  2482                       : Location::FpuRegisterLocation(Q1)); |  2472                       : Location::FpuRegisterLocation(Q1)); | 
|  2483     locs->AddTemp(Location::RequiresRegister()); |  2473     locs->AddTemp(Location::RequiresRegister()); | 
 |  2474     locs->AddTemp(Location::RequiresRegister()); | 
|  2484   } |  2475   } | 
|  2485   locs->set_out(0, Location::RequiresRegister()); |  2476   locs->set_out(0, Location::RequiresRegister()); | 
|  2486   return locs; |  2477   return locs; | 
|  2487 } |  2478 } | 
|  2488  |  2479  | 
|  2489  |  2480  | 
|  2490 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |  2481 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
|  2491   Register instance_reg = locs()->in(0).reg(); |  2482   const Register instance_reg = locs()->in(0).reg(); | 
|  2492   if (IsUnboxedLoad() && compiler->is_optimizing()) { |  2483   if (IsUnboxedLoad() && compiler->is_optimizing()) { | 
|  2493     const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |  2484     const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 
|  2494     const Register temp = locs()->temp(0).reg(); |  2485     const Register temp = locs()->temp(0).reg(); | 
|  2495     __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |  2486     __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 
|  2496     const intptr_t cid = field()->UnboxedFieldCid(); |  2487     const intptr_t cid = field()->UnboxedFieldCid(); | 
|  2497     switch (cid) { |  2488     switch (cid) { | 
|  2498       case kDoubleCid: |  2489       case kDoubleCid: | 
|  2499         __ Comment("UnboxedDoubleLoadFieldInstr"); |  2490         __ Comment("UnboxedDoubleLoadFieldInstr"); | 
|  2500         __ LoadDFromOffset(result, temp, |  2491         __ LoadDFromOffset(result, temp, | 
|  2501                            Double::value_offset() - kHeapObjectTag); |  2492                            Double::value_offset() - kHeapObjectTag); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  2512         break; |  2503         break; | 
|  2513       default: |  2504       default: | 
|  2514         UNREACHABLE(); |  2505         UNREACHABLE(); | 
|  2515     } |  2506     } | 
|  2516     return; |  2507     return; | 
|  2517   } |  2508   } | 
|  2518  |  2509  | 
|  2519   Label done; |  2510   Label done; | 
|  2520   Register result_reg = locs()->out(0).reg(); |  2511   Register result_reg = locs()->out(0).reg(); | 
|  2521   if (IsPotentialUnboxedLoad()) { |  2512   if (IsPotentialUnboxedLoad()) { | 
 |  2513     const DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); | 
|  2522     const Register temp = locs()->temp(1).reg(); |  2514     const Register temp = locs()->temp(1).reg(); | 
|  2523     const DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); |  2515     const Register temp2 = locs()->temp(2).reg(); | 
|  2524  |  2516  | 
|  2525     Label load_pointer; |  2517     Label load_pointer; | 
|  2526     Label load_double; |  2518     Label load_double; | 
|  2527     Label load_float32x4; |  2519     Label load_float32x4; | 
|  2528     Label load_float64x2; |  2520     Label load_float64x2; | 
|  2529  |  2521  | 
|  2530     __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |  2522     __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); | 
|  2531  |  2523  | 
|  2532     FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |  2524     FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); | 
|  2533     FieldAddress field_nullability_operand(result_reg, |  2525     FieldAddress field_nullability_operand(result_reg, | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|  2560       __ Bind(&load_double); |  2552       __ Bind(&load_double); | 
|  2561       BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |  2553       BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 
|  2562       compiler->AddSlowPathCode(slow_path); |  2554       compiler->AddSlowPathCode(slow_path); | 
|  2563  |  2555  | 
|  2564       __ TryAllocate(compiler->double_class(), |  2556       __ TryAllocate(compiler->double_class(), | 
|  2565                      slow_path->entry_label(), |  2557                      slow_path->entry_label(), | 
|  2566                      result_reg, |  2558                      result_reg, | 
|  2567                      temp); |  2559                      temp); | 
|  2568       __ Bind(slow_path->exit_label()); |  2560       __ Bind(slow_path->exit_label()); | 
|  2569       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |  2561       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 
|  2570       __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); |  2562       __ CopyDoubleField(result_reg, temp, TMP, temp2, value); | 
|  2571       __ StoreDToOffset(value, |  | 
|  2572                         result_reg, |  | 
|  2573                         Double::value_offset() - kHeapObjectTag); |  | 
|  2574       __ b(&done); |  2563       __ b(&done); | 
|  2575     } |  2564     } | 
|  2576  |  2565  | 
|  2577     { |  2566     { | 
|  2578       __ Bind(&load_float32x4); |  2567       __ Bind(&load_float32x4); | 
|  2579       BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); |  2568       BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 
|  2580       compiler->AddSlowPathCode(slow_path); |  2569       compiler->AddSlowPathCode(slow_path); | 
|  2581  |  2570  | 
|  2582       __ TryAllocate(compiler->float32x4_class(), |  2571       __ TryAllocate(compiler->float32x4_class(), | 
|  2583                      slow_path->entry_label(), |  2572                      slow_path->entry_label(), | 
|  2584                      result_reg, |  2573                      result_reg, | 
|  2585                      temp); |  2574                      temp); | 
|  2586       __ Bind(slow_path->exit_label()); |  2575       __ Bind(slow_path->exit_label()); | 
|  2587       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |  2576       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 
|  2588       __ LoadMultipleDFromOffset(value, 2, temp, |  2577       __ CopyFloat32x4Field(result_reg, temp, TMP, temp2, value); | 
|  2589           Float32x4::value_offset() - kHeapObjectTag); |  | 
|  2590       __ StoreMultipleDToOffset(value, 2, result_reg, |  | 
|  2591           Float32x4::value_offset() - kHeapObjectTag); |  | 
|  2592       __ b(&done); |  2578       __ b(&done); | 
|  2593     } |  2579     } | 
|  2594  |  2580  | 
|  2595     { |  2581     { | 
|  2596       __ Bind(&load_float64x2); |  2582       __ Bind(&load_float64x2); | 
|  2597       BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |  2583       BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | 
|  2598       compiler->AddSlowPathCode(slow_path); |  2584       compiler->AddSlowPathCode(slow_path); | 
|  2599  |  2585  | 
|  2600       __ TryAllocate(compiler->float64x2_class(), |  2586       __ TryAllocate(compiler->float64x2_class(), | 
|  2601                      slow_path->entry_label(), |  2587                      slow_path->entry_label(), | 
|  2602                      result_reg, |  2588                      result_reg, | 
|  2603                      temp); |  2589                      temp); | 
|  2604       __ Bind(slow_path->exit_label()); |  2590       __ Bind(slow_path->exit_label()); | 
|  2605       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |  2591       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 
|  2606       __ LoadMultipleDFromOffset(value, 2, temp, |  2592       __ CopyFloat64x2Field(result_reg, temp, TMP, temp2, value); | 
|  2607           Float64x2::value_offset() - kHeapObjectTag); |  | 
|  2608       __ StoreMultipleDToOffset(value, 2, result_reg, |  | 
|  2609           Float64x2::value_offset() - kHeapObjectTag); |  | 
|  2610       __ b(&done); |  2593       __ b(&done); | 
|  2611     } |  2594     } | 
|  2612  |  2595  | 
|  2613     __ Bind(&load_pointer); |  2596     __ Bind(&load_pointer); | 
|  2614   } |  2597   } | 
|  2615   __ LoadFromOffset(kWord, result_reg, |  2598   __ LoadFromOffset(kWord, result_reg, | 
|  2616                     instance_reg, offset_in_bytes() - kHeapObjectTag); |  2599                     instance_reg, offset_in_bytes() - kHeapObjectTag); | 
|  2617   __ Bind(&done); |  2600   __ Bind(&done); | 
|  2618 } |  2601 } | 
|  2619  |  2602  | 
| (...skipping 3662 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6282   compiler->GenerateCall(token_pos(), |  6265   compiler->GenerateCall(token_pos(), | 
|  6283                          &label, |  6266                          &label, | 
|  6284                          PcDescriptors::kOther, |  6267                          PcDescriptors::kOther, | 
|  6285                          locs()); |  6268                          locs()); | 
|  6286   __ Drop(ArgumentCount());  // Discard arguments. |  6269   __ Drop(ArgumentCount());  // Discard arguments. | 
|  6287 } |  6270 } | 
|  6288  |  6271  | 
|  6289 }  // namespace dart |  6272 }  // namespace dart | 
|  6290  |  6273  | 
|  6291 #endif  // defined TARGET_ARCH_ARM |  6274 #endif  // defined TARGET_ARCH_ARM | 
| OLD | NEW |