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 2941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2952 Register left = locs()->in(0).reg(); | 2952 Register left = locs()->in(0).reg(); |
2953 Register result = locs()->out(0).reg(); | 2953 Register result = locs()->out(0).reg(); |
2954 Label* deopt = NULL; | 2954 Label* deopt = NULL; |
2955 if (CanDeoptimize()) { | 2955 if (CanDeoptimize()) { |
2956 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); | 2956 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
2957 } | 2957 } |
2958 | 2958 |
2959 if (locs()->in(1).IsConstant()) { | 2959 if (locs()->in(1).IsConstant()) { |
2960 const Object& constant = locs()->in(1).constant(); | 2960 const Object& constant = locs()->in(1).constant(); |
2961 ASSERT(constant.IsSmi()); | 2961 ASSERT(constant.IsSmi()); |
2962 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); | 2962 const int32_t imm = reinterpret_cast<int32_t>(constant.raw()); |
2963 switch (op_kind()) { | 2963 switch (op_kind()) { |
2964 case Token::kSUB: { | |
2965 imm = -imm; // TODO(regis): What if deopt != NULL && imm == 0x80000000? | |
2966 // Fall through. | |
2967 } | |
2968 case Token::kADD: { | 2964 case Token::kADD: { |
2969 if (deopt == NULL) { | 2965 if (deopt == NULL) { |
2970 __ AddImmediate(result, left, imm); | 2966 __ AddImmediate(result, left, imm); |
2971 } else { | 2967 } else { |
2972 __ AddImmediateSetFlags(result, left, imm); | 2968 __ AddImmediateSetFlags(result, left, imm); |
2973 __ b(deopt, VS); | 2969 __ b(deopt, VS); |
2974 } | 2970 } |
2975 break; | 2971 break; |
2976 } | 2972 } |
| 2973 case Token::kSUB: { |
| 2974 if (deopt == NULL) { |
| 2975 __ AddImmediate(result, left, -imm); |
| 2976 } else { |
| 2977 // Negating imm and using AddImmediateSetFlags would not detect the |
| 2978 // overflow when imm == kMinInt32. |
| 2979 __ SubImmediateSetFlags(result, left, imm); |
| 2980 __ b(deopt, VS); |
| 2981 } |
| 2982 break; |
| 2983 } |
2977 case Token::kMUL: { | 2984 case Token::kMUL: { |
2978 // Keep left value tagged and untag right value. | 2985 // Keep left value tagged and untag right value. |
2979 const intptr_t value = Smi::Cast(constant).Value(); | 2986 const intptr_t value = Smi::Cast(constant).Value(); |
2980 if (deopt == NULL) { | 2987 if (deopt == NULL) { |
2981 if (value == 2) { | 2988 if (value == 2) { |
2982 __ mov(result, ShifterOperand(left, LSL, 1)); | 2989 __ mov(result, ShifterOperand(left, LSL, 1)); |
2983 } else { | 2990 } else { |
2984 __ LoadImmediate(IP, value); | 2991 __ LoadImmediate(IP, value); |
2985 __ mul(result, left, IP); | 2992 __ mul(result, left, IP); |
2986 } | 2993 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3037 __ rsb(result, result, ShifterOperand(0)); | 3044 __ rsb(result, result, ShifterOperand(0)); |
3038 } | 3045 } |
3039 __ SmiTag(result); | 3046 __ SmiTag(result); |
3040 break; | 3047 break; |
3041 } | 3048 } |
3042 case Token::kBIT_AND: { | 3049 case Token::kBIT_AND: { |
3043 // No overflow check. | 3050 // No overflow check. |
3044 ShifterOperand shifter_op; | 3051 ShifterOperand shifter_op; |
3045 if (ShifterOperand::CanHold(imm, &shifter_op)) { | 3052 if (ShifterOperand::CanHold(imm, &shifter_op)) { |
3046 __ and_(result, left, shifter_op); | 3053 __ and_(result, left, shifter_op); |
| 3054 } else if (ShifterOperand::CanHold(~imm, &shifter_op)) { |
| 3055 __ bic(result, left, shifter_op); |
3047 } else { | 3056 } else { |
3048 // TODO(regis): Try to use bic. | |
3049 __ LoadImmediate(IP, imm); | 3057 __ LoadImmediate(IP, imm); |
3050 __ and_(result, left, ShifterOperand(IP)); | 3058 __ and_(result, left, ShifterOperand(IP)); |
3051 } | 3059 } |
3052 break; | 3060 break; |
3053 } | 3061 } |
3054 case Token::kBIT_OR: { | 3062 case Token::kBIT_OR: { |
3055 // No overflow check. | 3063 // No overflow check. |
3056 ShifterOperand shifter_op; | 3064 ShifterOperand shifter_op; |
3057 if (ShifterOperand::CanHold(imm, &shifter_op)) { | 3065 if (ShifterOperand::CanHold(imm, &shifter_op)) { |
3058 __ orr(result, left, shifter_op); | 3066 __ orr(result, left, shifter_op); |
3059 } else { | 3067 } else { |
3060 // TODO(regis): Try to use orn. | |
3061 __ LoadImmediate(IP, imm); | 3068 __ LoadImmediate(IP, imm); |
3062 __ orr(result, left, ShifterOperand(IP)); | 3069 __ orr(result, left, ShifterOperand(IP)); |
3063 } | 3070 } |
3064 break; | 3071 break; |
3065 } | 3072 } |
3066 case Token::kBIT_XOR: { | 3073 case Token::kBIT_XOR: { |
3067 // No overflow check. | 3074 // No overflow check. |
3068 ShifterOperand shifter_op; | 3075 ShifterOperand shifter_op; |
3069 if (ShifterOperand::CanHold(imm, &shifter_op)) { | 3076 if (ShifterOperand::CanHold(imm, &shifter_op)) { |
3070 __ eor(result, left, shifter_op); | 3077 __ eor(result, left, shifter_op); |
(...skipping 3092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6163 compiler->GenerateCall(token_pos(), | 6170 compiler->GenerateCall(token_pos(), |
6164 &label, | 6171 &label, |
6165 PcDescriptors::kOther, | 6172 PcDescriptors::kOther, |
6166 locs()); | 6173 locs()); |
6167 __ Drop(ArgumentCount()); // Discard arguments. | 6174 __ Drop(ArgumentCount()); // Discard arguments. |
6168 } | 6175 } |
6169 | 6176 |
6170 } // namespace dart | 6177 } // namespace dart |
6171 | 6178 |
6172 #endif // defined TARGET_ARCH_ARM | 6179 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |