| 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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 4047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4058 __ vmovrrd(R0, R1, D0); | 4058 __ vmovrrd(R0, R1, D0); |
| 4059 __ vmovrrd(R2, R3, D1); | 4059 __ vmovrrd(R2, R3, D1); |
| 4060 __ CallRuntime(TargetFunction(), InputCount()); | 4060 __ CallRuntime(TargetFunction(), InputCount()); |
| 4061 __ vmovdrr(D0, R0, R1); | 4061 __ vmovdrr(D0, R0, R1); |
| 4062 __ vmovdrr(D1, R2, R3); | 4062 __ vmovdrr(D1, R2, R3); |
| 4063 #endif | 4063 #endif |
| 4064 __ Bind(&skip_call); | 4064 __ Bind(&skip_call); |
| 4065 } | 4065 } |
| 4066 | 4066 |
| 4067 | 4067 |
| 4068 LocationSummary* MergedMathInstr::MakeLocationSummary() const { |
| 4069 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 4070 const intptr_t kNumInputs = 2; |
| 4071 const intptr_t kNumTemps = 4; |
| 4072 LocationSummary* summary = |
| 4073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4074 summary->set_in(0, Location::RequiresRegister()); |
| 4075 summary->set_in(1, Location::RequiresRegister()); |
| 4076 summary->set_temp(0, Location::RequiresRegister()); |
| 4077 summary->set_temp(1, Location::RequiresFpuRegister()); |
| 4078 summary->set_temp(2, Location::RequiresRegister()); // result_div. |
| 4079 summary->set_temp(3, Location::RequiresRegister()); // result_mod. |
| 4080 summary->set_out(Location::RequiresRegister()); |
| 4081 return summary; |
| 4082 } |
| 4083 UNIMPLEMENTED(); |
| 4084 return NULL; |
| 4085 } |
| 4086 |
| 4087 |
| 4088 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4089 Label* deopt = NULL; |
| 4090 if (CanDeoptimize()) { |
| 4091 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); |
| 4092 } |
| 4093 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 4094 Register left = locs()->in(0).reg(); |
| 4095 Register right = locs()->in(1).reg(); |
| 4096 Register result = locs()->out().reg(); |
| 4097 // Handle divide by zero in runtime. |
| 4098 __ cmp(right, ShifterOperand(0)); |
| 4099 __ b(deopt, EQ); |
| 4100 Register temp = locs()->temp(0).reg(); |
| 4101 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 4102 Register result_div = locs()->temp(2).reg(); |
| 4103 Register result_mod = locs()->temp(3).reg(); |
| 4104 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 4105 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 4106 |
| 4107 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); |
| 4108 |
| 4109 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 4110 // case we cannot tag the result. |
| 4111 __ CompareImmediate(result_div, 0x40000000); |
| 4112 __ b(deopt, EQ); |
| 4113 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 4114 // result_mod <- left - right * result_div. |
| 4115 __ mls(result_mod, IP, result_div, temp); |
| 4116 __ SmiTag(result_div); |
| 4117 __ SmiTag(result_mod); |
| 4118 // Correct MOD result: |
| 4119 // res = left % right; |
| 4120 // if (res < 0) { |
| 4121 // if (right < 0) { |
| 4122 // res = res - right; |
| 4123 // } else { |
| 4124 // res = res + right; |
| 4125 // } |
| 4126 // } |
| 4127 Label done; |
| 4128 __ cmp(result_mod, ShifterOperand(0)); |
| 4129 __ b(&done, GE); |
| 4130 // Result is negative, adjust it. |
| 4131 __ cmp(right, ShifterOperand(0)); |
| 4132 __ sub(result_mod, result_mod, ShifterOperand(right), LT); |
| 4133 __ add(result_mod, result_mod, ShifterOperand(right), GE); |
| 4134 __ Bind(&done); |
| 4135 |
| 4136 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld))); |
| 4137 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays. |
| 4138 // [0]: divide resut, [1]: mod result. |
| 4139 __ mov(temp, ShifterOperand(0 + |
| 4140 FlowGraphCompiler::DataOffsetFor(kArrayCid) - kHeapObjectTag)); |
| 4141 Address store_address(result, temp, LSL, 0); |
| 4142 __ StoreIntoObjectNoBarrier(result, store_address, result_div); |
| 4143 __ add(temp, temp, ShifterOperand(kWordSize)); |
| 4144 __ StoreIntoObjectNoBarrier(result, store_address, result_mod); |
| 4145 return; |
| 4146 } |
| 4147 UNIMPLEMENTED(); |
| 4148 } |
| 4149 |
| 4150 |
| 4068 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4151 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 4069 return MakeCallSummary(); | 4152 return MakeCallSummary(); |
| 4070 } | 4153 } |
| 4071 | 4154 |
| 4072 | 4155 |
| 4073 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4156 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4074 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4157 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 4075 kDeoptPolymorphicInstanceCallTestFail); | 4158 kDeoptPolymorphicInstanceCallTestFail); |
| 4076 if (ic_data().NumberOfChecks() == 0) { | 4159 if (ic_data().NumberOfChecks() == 0) { |
| 4077 __ b(deopt); | 4160 __ b(deopt); |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4546 compiler->GenerateCall(token_pos(), | 4629 compiler->GenerateCall(token_pos(), |
| 4547 &label, | 4630 &label, |
| 4548 PcDescriptors::kOther, | 4631 PcDescriptors::kOther, |
| 4549 locs()); | 4632 locs()); |
| 4550 __ Drop(2); // Discard type arguments and receiver. | 4633 __ Drop(2); // Discard type arguments and receiver. |
| 4551 } | 4634 } |
| 4552 | 4635 |
| 4553 } // namespace dart | 4636 } // namespace dart |
| 4554 | 4637 |
| 4555 #endif // defined TARGET_ARCH_ARM | 4638 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |