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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 3032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 const Register temp = locs.temp(0).reg(); | 3043 const Register temp = locs.temp(0).reg(); |
3044 __ Lsl(temp, left, IP); | 3044 __ Lsl(temp, left, IP); |
3045 __ cmp(left, Operand(temp, ASR, IP)); | 3045 __ cmp(left, Operand(temp, ASR, IP)); |
3046 __ b(deopt, NE); // Overflow. | 3046 __ b(deopt, NE); // Overflow. |
3047 // Shift for result now we know there is no overflow. | 3047 // Shift for result now we know there is no overflow. |
3048 __ Lsl(result, left, IP); | 3048 __ Lsl(result, left, IP); |
3049 } | 3049 } |
3050 } | 3050 } |
3051 | 3051 |
3052 | 3052 |
| 3053 class CheckedSmiSlowPath : public SlowPathCode { |
| 3054 public: |
| 3055 CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index) |
| 3056 : instruction_(instruction), try_index_(try_index) { } |
| 3057 |
| 3058 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3059 if (Assembler::EmittingComments()) { |
| 3060 __ Comment("slow path smi operation"); |
| 3061 } |
| 3062 __ Bind(entry_label()); |
| 3063 LocationSummary* locs = instruction_->locs(); |
| 3064 Register result = locs->out(0).reg(); |
| 3065 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
| 3066 |
| 3067 compiler->SaveLiveRegisters(locs); |
| 3068 __ Push(locs->in(0).reg()); |
| 3069 __ Push(locs->in(1).reg()); |
| 3070 compiler->EmitMegamorphicInstanceCall( |
| 3071 *instruction_->call()->ic_data(), |
| 3072 instruction_->call()->ArgumentCount(), |
| 3073 instruction_->call()->deopt_id(), |
| 3074 instruction_->call()->token_pos(), |
| 3075 locs, |
| 3076 try_index_, |
| 3077 /* slow_path_argument_count = */ 2); |
| 3078 __ mov(result, Operand(R0)); |
| 3079 compiler->RestoreLiveRegisters(locs); |
| 3080 __ b(exit_label()); |
| 3081 } |
| 3082 |
| 3083 private: |
| 3084 CheckedSmiOpInstr* instruction_; |
| 3085 intptr_t try_index_; |
| 3086 }; |
| 3087 |
| 3088 |
| 3089 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, |
| 3090 bool opt) const { |
| 3091 const intptr_t kNumInputs = 2; |
| 3092 const intptr_t kNumTemps = 0; |
| 3093 LocationSummary* summary = new(zone) LocationSummary( |
| 3094 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3095 summary->set_in(0, Location::RequiresRegister()); |
| 3096 summary->set_in(1, Location::RequiresRegister()); |
| 3097 summary->set_out(0, Location::RequiresRegister()); |
| 3098 return summary; |
| 3099 } |
| 3100 |
| 3101 |
| 3102 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3103 CheckedSmiSlowPath* slow_path = |
| 3104 new CheckedSmiSlowPath(this, compiler->CurrentTryIndex()); |
| 3105 compiler->AddSlowPathCode(slow_path); |
| 3106 // Test operands if necessary. |
| 3107 Register left = locs()->in(0).reg(); |
| 3108 Register right = locs()->in(1).reg(); |
| 3109 Register result = locs()->out(0).reg(); |
| 3110 __ orr(result, left, Operand(right)); |
| 3111 __ tst(result, Operand(kSmiTagMask)); |
| 3112 __ b(slow_path->entry_label(), NE); |
| 3113 switch (op_kind()) { |
| 3114 case Token::kADD: |
| 3115 __ adds(result, left, Operand(right)); |
| 3116 __ b(slow_path->entry_label(), VS); |
| 3117 break; |
| 3118 case Token::kSUB: |
| 3119 __ subs(result, left, Operand(right)); |
| 3120 __ b(slow_path->entry_label(), VS); |
| 3121 break; |
| 3122 case Token::kBIT_OR: |
| 3123 // Operation part of combined smi check. |
| 3124 break; |
| 3125 case Token::kBIT_AND: |
| 3126 __ and_(result, left, Operand(right)); |
| 3127 break; |
| 3128 case Token::kBIT_XOR: |
| 3129 __ eor(result, left, Operand(right)); |
| 3130 break; |
| 3131 default: |
| 3132 UNIMPLEMENTED(); |
| 3133 } |
| 3134 __ Bind(slow_path->exit_label()); |
| 3135 } |
| 3136 |
| 3137 |
3053 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, | 3138 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, |
3054 bool opt) const { | 3139 bool opt) const { |
3055 const intptr_t kNumInputs = 2; | 3140 const intptr_t kNumInputs = 2; |
3056 // Calculate number of temporaries. | 3141 // Calculate number of temporaries. |
3057 intptr_t num_temps = 0; | 3142 intptr_t num_temps = 0; |
3058 if (op_kind() == Token::kTRUNCDIV) { | 3143 if (op_kind() == Token::kTRUNCDIV) { |
3059 if (RightIsPowerOfTwoConstant()) { | 3144 if (RightIsPowerOfTwoConstant()) { |
3060 num_temps = 1; | 3145 num_temps = 1; |
3061 } else { | 3146 } else { |
3062 num_temps = 2; | 3147 num_temps = 2; |
(...skipping 3761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6824 1, | 6909 1, |
6825 locs()); | 6910 locs()); |
6826 __ Drop(1); | 6911 __ Drop(1); |
6827 __ Pop(result); | 6912 __ Pop(result); |
6828 } | 6913 } |
6829 | 6914 |
6830 | 6915 |
6831 } // namespace dart | 6916 } // namespace dart |
6832 | 6917 |
6833 #endif // defined TARGET_ARCH_ARM | 6918 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |