Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: runtime/vm/intermediate_language_arm64.cc

Issue 670263007: IR refactoring: consolidate all boxing and unboxing instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 3036 matching lines...) Expand 10 before | Expand all | Expand 10 after
3047 } else if (right_cid == kSmiCid) { 3047 } else if (right_cid == kSmiCid) {
3048 __ tsti(left, Immediate(kSmiTagMask)); 3048 __ tsti(left, Immediate(kSmiTagMask));
3049 } else { 3049 } else {
3050 __ orr(TMP, left, Operand(right)); 3050 __ orr(TMP, left, Operand(right));
3051 __ tsti(TMP, Immediate(kSmiTagMask)); 3051 __ tsti(TMP, Immediate(kSmiTagMask));
3052 } 3052 }
3053 __ b(deopt, EQ); 3053 __ b(deopt, EQ);
3054 } 3054 }
3055 3055
3056 3056
3057 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, 3057 LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
3058 bool opt) const { 3058 bool opt) const {
3059 const intptr_t kNumInputs = 1; 3059 const intptr_t kNumInputs = 1;
3060 const intptr_t kNumTemps = 1; 3060 const intptr_t kNumTemps = 1;
3061 LocationSummary* summary = new(isolate) LocationSummary( 3061 LocationSummary* summary = new(isolate) LocationSummary(
3062 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3062 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3063 summary->set_in(0, Location::RequiresFpuRegister()); 3063 summary->set_in(0, Location::RequiresFpuRegister());
3064 summary->set_temp(0, Location::RequiresRegister()); 3064 summary->set_temp(0, Location::RequiresRegister());
3065 summary->set_out(0, Location::RequiresRegister()); 3065 summary->set_out(0, Location::RequiresRegister());
3066 return summary; 3066 return summary;
3067 } 3067 }
3068 3068
3069 3069
3070 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3070 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3071 const Register out_reg = locs()->out(0).reg(); 3071 const Register out_reg = locs()->out(0).reg();
3072 const Register temp_reg = locs()->temp(0).reg(); 3072 const Register temp_reg = locs()->temp(0).reg();
3073 const VRegister value = locs()->in(0).fpu_reg(); 3073 const VRegister value = locs()->in(0).fpu_reg();
3074 3074
3075 BoxAllocationSlowPath::Allocate( 3075 BoxAllocationSlowPath::Allocate(
3076 compiler, this, compiler->double_class(), out_reg, temp_reg); 3076 compiler,
3077 __ StoreDFieldToOffset(value, out_reg, Double::value_offset(), PP); 3077 this,
3078 compiler->BoxClassFor(from_representation()),
3079 out_reg,
3080 temp_reg);
3081
3082 switch (from_representation()) {
3083 case kUnboxedDouble:
3084 __ StoreDFieldToOffset(value, out_reg, ValueOffset(), PP);
3085 break;
3086 case kUnboxedFloat32x4:
3087 case kUnboxedFloat64x2:
3088 case kUnboxedInt32x4:
3089 __ StoreQFieldToOffset(value, out_reg, ValueOffset(), PP);
3090 break;
3091 default:
3092 UNREACHABLE();
3093 break;
3094 }
3078 } 3095 }
3079 3096
3080 3097
3081 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, 3098 LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
3082 bool opt) const { 3099 bool opt) const {
3083 const intptr_t kNumInputs = 1; 3100 const intptr_t kNumInputs = 1;
3084 const intptr_t kNumTemps = 0; 3101 const intptr_t kNumTemps = 0;
3085 LocationSummary* summary = new(isolate) LocationSummary( 3102 LocationSummary* summary = new(isolate) LocationSummary(
3086 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3103 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3087 summary->set_in(0, Location::RequiresRegister()); 3104 summary->set_in(0, Location::RequiresRegister());
3088 summary->set_out(0, Location::RequiresFpuRegister()); 3105 summary->set_out(0, Location::RequiresFpuRegister());
3089 return summary; 3106 return summary;
3090 } 3107 }
3091 3108
3092 3109
3093 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3110 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
3094 CompileType* value_type = value()->Type(); 3111 const Register box = locs()->in(0).reg();
3095 const intptr_t value_cid = value_type->ToCid();
3096 const Register value = locs()->in(0).reg();
3097 const VRegister result = locs()->out(0).fpu_reg();
3098 3112
3099 if (value_cid == kDoubleCid) { 3113 switch (representation()) {
3100 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP); 3114 case kUnboxedMint: {
3101 } else if (value_cid == kSmiCid) { 3115 UNIMPLEMENTED();
3102 __ SmiUntag(TMP, value); // Untag input before conversion. 3116 break;
3103 __ scvtfdx(result, TMP); 3117 }
3118
3119 case kUnboxedDouble: {
3120 const VRegister result = locs()->out(0).fpu_reg();
3121 __ LoadDFieldFromOffset(result, box, ValueOffset(), PP);
3122 break;
3123 }
3124
3125 case kUnboxedFloat32x4:
3126 case kUnboxedFloat64x2:
3127 case kUnboxedInt32x4: {
3128 const VRegister result = locs()->out(0).fpu_reg();
3129 __ LoadQFieldFromOffset(result, box, ValueOffset(), PP);
3130 break;
3131 }
3132
3133 default:
3134 UNREACHABLE();
3135 break;
3136 }
3137 }
3138
3139
3140 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
3141 const Register box = locs()->in(0).reg();
3142
3143 switch (representation()) {
3144 case kUnboxedMint: {
3145 UNIMPLEMENTED();
3146 break;
3147 }
3148
3149 case kUnboxedDouble: {
3150 const VRegister result = locs()->out(0).fpu_reg();
3151 __ SmiUntag(TMP, box);
3152 __ scvtfdx(result, TMP);
3153 break;
3154 }
3155
3156 default:
3157 UNREACHABLE();
3158 break;
3159 }
3160 }
3161
3162
3163 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3164 const intptr_t value_cid = value()->Type()->ToCid();
3165 const intptr_t box_cid = BoxCid();
3166
3167 if (value_cid == box_cid) {
3168 EmitLoadFromBox(compiler);
3169 } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
3170 EmitSmiConversion(compiler);
3104 } else { 3171 } else {
3172 const Register box = locs()->in(0).reg();
3105 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), 3173 Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
3106 ICData::kDeoptBinaryDoubleOp); 3174 ICData::kDeoptCheckClass);
3107 if (value_type->is_nullable() && 3175 Label is_smi;
3108 (value_type->ToNullableCid() == kDoubleCid)) { 3176
3109 __ CompareObject(value, Object::null_object(), PP); 3177 if ((value()->Type()->ToNullableCid() == box_cid) &&
3178 value()->Type()->is_nullable()) {
3179 __ CompareObject(box, Object::null_object(), PP);
3110 __ b(deopt, EQ); 3180 __ b(deopt, EQ);
3111 // It must be double now.
3112 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
3113 } else { 3181 } else {
3114 Label is_smi, done; 3182 __ tsti(box, Immediate(kSmiTagMask));
3115 __ tsti(value, Immediate(kSmiTagMask)); 3183 __ b(CanConvertSmi() ? &is_smi : deopt, EQ);
3116 __ b(&is_smi, EQ); 3184 __ CompareClassId(box, box_cid, PP);
3117 __ CompareClassId(value, kDoubleCid, PP);
3118 __ b(deopt, NE); 3185 __ b(deopt, NE);
3119 __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP); 3186 }
3187
3188 EmitLoadFromBox(compiler);
3189
3190 if (is_smi.IsLinked()) {
3191 Label done;
3120 __ b(&done); 3192 __ b(&done);
3121 __ Bind(&is_smi); 3193 __ Bind(&is_smi);
3122 __ SmiUntag(TMP, value); // Copy and untag. 3194 EmitSmiConversion(compiler);
3123 __ scvtfdx(result, TMP);
3124 __ Bind(&done); 3195 __ Bind(&done);
3125 } 3196 }
3126 } 3197 }
3127 } 3198 }
3128 3199
3129 3200
3130 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 3201 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
3131 bool opt) const { 3202 bool opt) const {
3203 ASSERT((from_representation() == kUnboxedInt32) ||
3204 (from_representation() == kUnboxedUint32));
3132 const intptr_t kNumInputs = 1; 3205 const intptr_t kNumInputs = 1;
3133 const intptr_t kNumTemps = 1; 3206 const intptr_t kNumTemps = 0;
3134 LocationSummary* summary = new(isolate) LocationSummary( 3207 LocationSummary* summary = new(isolate) LocationSummary(
3135 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3208 isolate,
3136 summary->set_in(0, Location::RequiresFpuRegister()); 3209 kNumInputs,
3137 summary->set_temp(0, Location::RequiresRegister()); 3210 kNumTemps,
3211 LocationSummary::kNoCall);
3212 summary->set_in(0, Location::RequiresRegister());
3138 summary->set_out(0, Location::RequiresRegister()); 3213 summary->set_out(0, Location::RequiresRegister());
3139 return summary; 3214 return summary;
3140 } 3215 }
3141 3216
3142 3217
3143 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3218 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3144 const Register out_reg = locs()->out(0).reg(); 3219 Register value = locs()->in(0).reg();
3145 const Register temp_reg = locs()->temp(0).reg(); 3220 Register out = locs()->out(0).reg();
3146 const VRegister value = locs()->in(0).fpu_reg(); 3221 ASSERT(value != out);
3147 3222
3148 BoxAllocationSlowPath::Allocate( 3223 ASSERT(kSmiTagSize == 1);
3149 compiler, this, compiler->float32x4_class(), out_reg, temp_reg); 3224 // TODO(vegorov) implement and use UBFM/SBFM for this.
3150 __ StoreQFieldToOffset(value, out_reg, Float32x4::value_offset(), PP); 3225 __ LslImmediate(out, value, 32);
3226 if (from_representation() == kUnboxedInt32) {
3227 __ AsrImmediate(out, out, 32 - kSmiTagSize);
3228 } else {
3229 ASSERT(from_representation() == kUnboxedUint32);
3230 __ LsrImmediate(out, out, 32 - kSmiTagSize);
3231 }
3151 } 3232 }
3152 3233
3153 3234
3154 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 3235 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt64Instr)
3236
3237
3238 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
3155 bool opt) const { 3239 bool opt) const {
3156 const intptr_t kNumInputs = 1; 3240 const intptr_t kNumInputs = 1;
3157 const intptr_t kNumTemps = 0; 3241 const intptr_t kNumTemps = 0;
3158 LocationSummary* summary = new(isolate) LocationSummary( 3242 LocationSummary* summary = new(isolate) LocationSummary(
3159 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3243 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3160 summary->set_in(0, Location::RequiresRegister()); 3244 summary->set_in(0, Location::RequiresRegister());
3161 summary->set_out(0, Location::RequiresFpuRegister());
3162 return summary;
3163 }
3164
3165
3166 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3167 const intptr_t value_cid = value()->Type()->ToCid();
3168 const Register value = locs()->in(0).reg();
3169 const VRegister result = locs()->out(0).fpu_reg();
3170
3171 if (value_cid != kFloat32x4Cid) {
3172 Label* deopt =
3173 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
3174 __ tsti(value, Immediate(kSmiTagMask));
3175 __ b(deopt, EQ);
3176 __ CompareClassId(value, kFloat32x4Cid, PP);
3177 __ b(deopt, NE);
3178 }
3179
3180 __ LoadQFieldFromOffset(result, value, Float32x4::value_offset(), PP);
3181 }
3182
3183
3184 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
3185 bool opt) const {
3186 const intptr_t kNumInputs = 1;
3187 const intptr_t kNumTemps = 1;
3188 LocationSummary* summary = new(isolate) LocationSummary(
3189 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3190 summary->set_in(0, Location::RequiresFpuRegister());
3191 summary->set_temp(0, Location::RequiresRegister());
3192 summary->set_out(0, Location::RequiresRegister()); 3245 summary->set_out(0, Location::RequiresRegister());
3193 return summary; 3246 return summary;
3194 } 3247 }
3195 3248
3196 3249
3197 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3250 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3198 const Register out_reg = locs()->out(0).reg(); 3251 const intptr_t value_cid = value()->Type()->ToCid();
3199 const Register temp_reg = locs()->temp(0).reg(); 3252 const Register out = locs()->out(0).reg();
3200 const VRegister value = locs()->in(0).fpu_reg(); 3253 const Register value = locs()->in(0).reg();
3254 Label* deopt = CanDeoptimize() ?
3255 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
3201 3256
3202 BoxAllocationSlowPath::Allocate( 3257 if (value_cid == kSmiCid) {
3203 compiler, this, compiler->float64x2_class(), out_reg, temp_reg); 3258 __ SmiUntag(out, value);
3204 __ StoreQFieldToOffset(value, out_reg, Float64x2::value_offset(), PP); 3259 } else if (value_cid == kMintCid) {
3260 __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
3261 } else {
3262 Label done;
3263 __ SmiUntag(out, value);
3264 __ TestImmediate(value, kSmiTagMask, PP);
3265 __ b(&done, EQ);
3266 __ CompareClassId(value, kMintCid, PP);
3267 __ b(deopt, NE);
3268 __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
3269 __ Bind(&done);
3270 }
3271
3272 // TODO(vegorov): as it is implemented right now truncating unboxing would
3273 // leave "garbage" in the higher word.
3274 if (!is_truncating() && (deopt != NULL)) {
3275 ASSERT(representation() == kUnboxedInt32);
3276 __ cmp(out, Operand(out, SXTW, 0));
3277 __ b(deopt, NE);
3278 }
3205 } 3279 }
3206 3280
3207 3281
3208 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
3209 bool opt) const {
3210 const intptr_t kNumInputs = 1;
3211 const intptr_t kNumTemps = 0;
3212 LocationSummary* summary = new(isolate) LocationSummary(
3213 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3214 summary->set_in(0, Location::RequiresRegister());
3215 summary->set_out(0, Location::RequiresFpuRegister());
3216 return summary;
3217 }
3218
3219
3220 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3221 const intptr_t value_cid = value()->Type()->ToCid();
3222 const Register value = locs()->in(0).reg();
3223 const VRegister result = locs()->out(0).fpu_reg();
3224
3225 if (value_cid != kFloat64x2Cid) {
3226 Label* deopt =
3227 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
3228 __ tsti(value, Immediate(kSmiTagMask));
3229 __ b(deopt, EQ);
3230 __ CompareClassId(value, kFloat64x2Cid, PP);
3231 __ b(deopt, NE);
3232 }
3233
3234 __ LoadQFieldFromOffset(result, value, Float64x2::value_offset(), PP);
3235 }
3236
3237
3238 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
3239 bool opt) const {
3240 const intptr_t kNumInputs = 1;
3241 const intptr_t kNumTemps = 1;
3242 LocationSummary* summary = new(isolate) LocationSummary(
3243 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3244 summary->set_in(0, Location::RequiresFpuRegister());
3245 summary->set_temp(0, Location::RequiresRegister());
3246 summary->set_out(0, Location::RequiresRegister());
3247 return summary;
3248 }
3249
3250
3251 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3252 const Register out_reg = locs()->out(0).reg();
3253 const Register temp_reg = locs()->temp(0).reg();
3254 const VRegister value = locs()->in(0).fpu_reg();
3255 BoxAllocationSlowPath::Allocate(
3256 compiler, this, compiler->int32x4_class(), out_reg, temp_reg);
3257 __ StoreQFieldToOffset(value, out_reg, Int32x4::value_offset(), PP);
3258 }
3259
3260
3261 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
3262 bool opt) const {
3263 const intptr_t kNumInputs = 1;
3264 const intptr_t kNumTemps = 0;
3265 LocationSummary* summary = new(isolate) LocationSummary(
3266 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3267 summary->set_in(0, Location::RequiresRegister());
3268 summary->set_out(0, Location::RequiresFpuRegister());
3269 return summary;
3270 }
3271
3272
3273 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3274 const intptr_t value_cid = value()->Type()->ToCid();
3275 const Register value = locs()->in(0).reg();
3276 const VRegister result = locs()->out(0).fpu_reg();
3277
3278 if (value_cid != kInt32x4Cid) {
3279 Label* deopt =
3280 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
3281 __ tsti(value, Immediate(kSmiTagMask));
3282 __ b(deopt, EQ);
3283 __ CompareClassId(value, kInt32x4Cid, PP);
3284 __ b(deopt, NE);
3285 }
3286
3287 __ LoadQFieldFromOffset(result, value, Int32x4::value_offset(), PP);
3288 }
3289
3290
3291 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, 3282 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate,
3292 bool opt) const { 3283 bool opt) const {
3293 const intptr_t kNumInputs = 2; 3284 const intptr_t kNumInputs = 2;
3294 const intptr_t kNumTemps = 0; 3285 const intptr_t kNumTemps = 0;
3295 LocationSummary* summary = new(isolate) LocationSummary( 3286 LocationSummary* summary = new(isolate) LocationSummary(
3296 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3287 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3297 summary->set_in(0, Location::RequiresFpuRegister()); 3288 summary->set_in(0, Location::RequiresFpuRegister());
3298 summary->set_in(1, Location::RequiresFpuRegister()); 3289 summary->set_in(1, Location::RequiresFpuRegister());
3299 summary->set_out(0, Location::RequiresFpuRegister()); 3290 summary->set_out(0, Location::RequiresFpuRegister());
3300 return summary; 3291 return summary;
(...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after
5175 } 5166 }
5176 } else { 5167 } else {
5177 const Register length = length_loc.reg(); 5168 const Register length = length_loc.reg();
5178 const Register index = index_loc.reg(); 5169 const Register index = index_loc.reg();
5179 __ CompareRegisters(index, length); 5170 __ CompareRegisters(index, length);
5180 __ b(deopt, CS); 5171 __ b(deopt, CS);
5181 } 5172 }
5182 } 5173 }
5183 5174
5184 5175
5185 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5186 bool opt) const {
5187 UNIMPLEMENTED();
5188 return NULL;
5189 }
5190
5191
5192 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5193 UNIMPLEMENTED();
5194 }
5195
5196
5197 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5198 bool opt) const {
5199 UNIMPLEMENTED();
5200 return NULL;
5201 }
5202
5203
5204 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5205 UNIMPLEMENTED();
5206 }
5207
5208
5209 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5176 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5210 bool opt) const { 5177 bool opt) const {
5211 UNIMPLEMENTED(); 5178 UNIMPLEMENTED();
5212 return NULL; 5179 return NULL;
5213 } 5180 }
5214 5181
5215 5182
5216 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5183 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5217 UNIMPLEMENTED(); 5184 UNIMPLEMENTED();
5218 } 5185 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
5262 return CompileType::FromCid(kSmiCid); 5229 return CompileType::FromCid(kSmiCid);
5263 } 5230 }
5264 5231
5265 5232
5266 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) 5233 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr)
5267 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) 5234 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr)
5268 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) 5235 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr)
5269 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5236 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5270 5237
5271 5238
5272 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
5273 bool opt) const {
5274 const intptr_t kNumInputs = 1;
5275 const intptr_t kNumTemps = 0;
5276 LocationSummary* summary = new(isolate) LocationSummary(
5277 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5278 summary->set_in(0, Location::RequiresRegister());
5279 summary->set_out(0, Location::RequiresRegister());
5280 return summary;
5281 }
5282
5283
5284 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5285 const intptr_t value_cid = value()->Type()->ToCid();
5286 const Register out = locs()->out(0).reg();
5287 const Register value = locs()->in(0).reg();
5288 Label* deopt = CanDeoptimize() ?
5289 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
5290
5291 if (value_cid == kSmiCid) {
5292 __ SmiUntag(out, value);
5293 } else if (value_cid == kMintCid) {
5294 __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
5295 } else {
5296 Label done;
5297 __ SmiUntag(out, value);
5298 __ TestImmediate(value, kSmiTagMask, PP);
5299 __ b(&done, EQ);
5300 __ CompareClassId(value, kMintCid, PP);
5301 __ b(deopt, NE);
5302 __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
5303 __ Bind(&done);
5304 }
5305
5306 // TODO(vegorov): as it is implemented right now truncating unboxing would
5307 // leave "garbage" in the higher word.
5308 if (!is_truncating() && (deopt != NULL)) {
5309 ASSERT(representation() == kUnboxedInt32);
5310 __ cmp(out, Operand(out, SXTW, 0));
5311 __ b(deopt, NE);
5312 }
5313 }
5314
5315
5316 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
5317 bool opt) const {
5318 ASSERT((from_representation() == kUnboxedInt32) ||
5319 (from_representation() == kUnboxedUint32));
5320 const intptr_t kNumInputs = 1;
5321 const intptr_t kNumTemps = 0;
5322 LocationSummary* summary = new(isolate) LocationSummary(
5323 isolate,
5324 kNumInputs,
5325 kNumTemps,
5326 LocationSummary::kNoCall);
5327 summary->set_in(0, Location::RequiresRegister());
5328 summary->set_out(0, Location::RequiresRegister());
5329 return summary;
5330 }
5331
5332
5333 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5334 Register value = locs()->in(0).reg();
5335 Register out = locs()->out(0).reg();
5336 ASSERT(value != out);
5337
5338 ASSERT(kSmiTagSize == 1);
5339 // TODO(vegorov) implement and use UBFM/SBFM for this.
5340 __ LslImmediate(out, value, 32);
5341 if (from_representation() == kUnboxedInt32) {
5342 __ AsrImmediate(out, out, 32 - kSmiTagSize);
5343 } else {
5344 ASSERT(from_representation() == kUnboxedUint32);
5345 __ LsrImmediate(out, out, 32 - kSmiTagSize);
5346 }
5347 }
5348
5349
5350 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, 5239 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
5351 bool opt) const { 5240 bool opt) const {
5352 const intptr_t kNumInputs = 1; 5241 const intptr_t kNumInputs = 1;
5353 const intptr_t kNumTemps = 0; 5242 const intptr_t kNumTemps = 0;
5354 LocationSummary* summary = new(isolate) LocationSummary( 5243 LocationSummary* summary = new(isolate) LocationSummary(
5355 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5244 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5356 if (from() == kUnboxedMint) { 5245 if (from() == kUnboxedMint) {
5357 UNREACHABLE(); 5246 UNREACHABLE();
5358 } else if (to() == kUnboxedMint) { 5247 } else if (to() == kUnboxedMint) {
5359 UNREACHABLE(); 5248 UNREACHABLE();
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
5605 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 5494 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
5606 #if defined(DEBUG) 5495 #if defined(DEBUG)
5607 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); 5496 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP);
5608 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); 5497 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP);
5609 #endif 5498 #endif
5610 } 5499 }
5611 5500
5612 } // namespace dart 5501 } // namespace dart
5613 5502
5614 #endif // defined TARGET_ARCH_ARM64 5503 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698