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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 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
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.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) 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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 11 matching lines...) Expand all
22 #include "vm/symbols.h" 22 #include "vm/symbols.h"
23 23
24 #define __ compiler->assembler()-> 24 #define __ compiler->assembler()->
25 #define Z (compiler->zone()) 25 #define Z (compiler->zone())
26 26
27 namespace dart { 27 namespace dart {
28 28
29 // Generic summary for call instructions that have all arguments pushed 29 // Generic summary for call instructions that have all arguments pushed
30 // on the stack and return the result in a fixed register V0. 30 // on the stack and return the result in a fixed register V0.
31 LocationSummary* Instruction::MakeCallSummary(Zone* zone) { 31 LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
32 LocationSummary* result = new(zone) LocationSummary( 32 LocationSummary* result =
33 zone, 0, 0, LocationSummary::kCall); 33 new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
34 result->set_out(0, Location::RegisterLocation(V0)); 34 result->set_out(0, Location::RegisterLocation(V0));
35 return result; 35 return result;
36 } 36 }
37 37
38 38
39 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone, 39 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone,
40 bool opt) const { 40 bool opt) const {
41 const intptr_t kNumInputs = 1; 41 const intptr_t kNumInputs = 1;
42 const intptr_t kNumTemps = 0; 42 const intptr_t kNumTemps = 0;
43 LocationSummary* locs = new(zone) LocationSummary( 43 LocationSummary* locs = new (zone)
44 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 44 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
45 locs->set_in(0, Location::AnyOrConstant(value())); 45 locs->set_in(0, Location::AnyOrConstant(value()));
46 return locs; 46 return locs;
47 } 47 }
48 48
49 49
50 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 50 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
51 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode 51 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode
52 // where PushArgument is handled by BindInstr::EmitNativeCode. 52 // where PushArgument is handled by BindInstr::EmitNativeCode.
53 __ Comment("PushArgumentInstr"); 53 __ Comment("PushArgumentInstr");
54 if (compiler->is_optimizing()) { 54 if (compiler->is_optimizing()) {
55 Location value = locs()->in(0); 55 Location value = locs()->in(0);
56 if (value.IsRegister()) { 56 if (value.IsRegister()) {
57 __ Push(value.reg()); 57 __ Push(value.reg());
58 } else if (value.IsConstant()) { 58 } else if (value.IsConstant()) {
59 __ PushObject(value.constant()); 59 __ PushObject(value.constant());
60 } else { 60 } else {
61 ASSERT(value.IsStackSlot()); 61 ASSERT(value.IsStackSlot());
62 const intptr_t value_offset = value.ToStackSlotOffset(); 62 const intptr_t value_offset = value.ToStackSlotOffset();
63 __ LoadFromOffset(TMP, FP, value_offset); 63 __ LoadFromOffset(TMP, FP, value_offset);
64 __ Push(TMP); 64 __ Push(TMP);
65 } 65 }
66 } 66 }
67 } 67 }
68 68
69 69
70 LocationSummary* ReturnInstr::MakeLocationSummary(Zone* zone, 70 LocationSummary* ReturnInstr::MakeLocationSummary(Zone* zone, bool opt) const {
71 bool opt) const {
72 const intptr_t kNumInputs = 1; 71 const intptr_t kNumInputs = 1;
73 const intptr_t kNumTemps = 0; 72 const intptr_t kNumTemps = 0;
74 LocationSummary* locs = new(zone) LocationSummary( 73 LocationSummary* locs = new (zone)
75 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 74 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
76 locs->set_in(0, Location::RegisterLocation(V0)); 75 locs->set_in(0, Location::RegisterLocation(V0));
77 return locs; 76 return locs;
78 } 77 }
79 78
80 79
81 // Attempt optimized compilation at return instruction instead of at the entry. 80 // Attempt optimized compilation at return instruction instead of at the entry.
82 // The entry needs to be patchable, no inlined objects are allowed in the area 81 // The entry needs to be patchable, no inlined objects are allowed in the area
83 // that will be overwritten by the patch instructions: a branch macro sequence. 82 // that will be overwritten by the patch instructions: a branch macro sequence.
84 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 83 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
85 __ Comment("ReturnInstr"); 84 __ Comment("ReturnInstr");
(...skipping 18 matching lines...) Expand all
104 __ break_(0); 103 __ break_(0);
105 104
106 __ Bind(&stack_ok); 105 __ Bind(&stack_ok);
107 #endif 106 #endif
108 __ LeaveDartFrameAndReturn(); 107 __ LeaveDartFrameAndReturn();
109 } 108 }
110 109
111 110
112 static Condition NegateCondition(Condition condition) { 111 static Condition NegateCondition(Condition condition) {
113 switch (condition.rel_op()) { 112 switch (condition.rel_op()) {
114 case AL: condition.set_rel_op(NV); break; 113 case AL:
115 case NV: condition.set_rel_op(AL); break; 114 condition.set_rel_op(NV);
116 case EQ: condition.set_rel_op(NE); break; 115 break;
117 case NE: condition.set_rel_op(EQ); break; 116 case NV:
118 case LT: condition.set_rel_op(GE); break; 117 condition.set_rel_op(AL);
119 case LE: condition.set_rel_op(GT); break; 118 break;
120 case GT: condition.set_rel_op(LE); break; 119 case EQ:
121 case GE: condition.set_rel_op(LT); break; 120 condition.set_rel_op(NE);
122 case ULT: condition.set_rel_op(UGE); break; 121 break;
123 case ULE: condition.set_rel_op(UGT); break; 122 case NE:
124 case UGT: condition.set_rel_op(ULE); break; 123 condition.set_rel_op(EQ);
125 case UGE: condition.set_rel_op(ULT); break; 124 break;
125 case LT:
126 condition.set_rel_op(GE);
127 break;
128 case LE:
129 condition.set_rel_op(GT);
130 break;
131 case GT:
132 condition.set_rel_op(LE);
133 break;
134 case GE:
135 condition.set_rel_op(LT);
136 break;
137 case ULT:
138 condition.set_rel_op(UGE);
139 break;
140 case ULE:
141 condition.set_rel_op(UGT);
142 break;
143 case UGT:
144 condition.set_rel_op(ULE);
145 break;
146 case UGE:
147 condition.set_rel_op(ULT);
148 break;
126 default: 149 default:
127 UNREACHABLE(); 150 UNREACHABLE();
128 } 151 }
129 return condition; 152 return condition;
130 } 153 }
131 154
132 155
133 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone, 156 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
134 bool opt) const { 157 bool opt) const {
135 comparison()->InitializeLocationSummary(zone, opt); 158 comparison()->InitializeLocationSummary(zone, opt);
(...skipping 12 matching lines...) Expand all
148 intptr_t temp = true_value; 171 intptr_t temp = true_value;
149 true_value = false_value; 172 true_value = false_value;
150 false_value = temp; 173 false_value = temp;
151 swapped = true; 174 swapped = true;
152 } 175 }
153 176
154 // Initialize result with the true value. 177 // Initialize result with the true value.
155 __ LoadImmediate(result, Smi::RawValue(true_value)); 178 __ LoadImmediate(result, Smi::RawValue(true_value));
156 179
157 // Emit comparison code. This must not overwrite the result register. 180 // Emit comparison code. This must not overwrite the result register.
158 BranchLabels labels = { NULL, NULL, NULL }; // Emit branch-free code. 181 BranchLabels labels = {NULL, NULL, NULL}; // Emit branch-free code.
159 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 182 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
160 if (swapped) { 183 if (swapped) {
161 true_condition = NegateCondition(true_condition); 184 true_condition = NegateCondition(true_condition);
162 } 185 }
163 186
164 // Evaluate condition and provide result in CMPRES1. 187 // Evaluate condition and provide result in CMPRES1.
165 Register left = true_condition.left(); 188 Register left = true_condition.left();
166 Register right = true_condition.right(); 189 Register right = true_condition.right();
167 bool zero_is_false = true; // Zero in CMPRES1 indicates a false condition. 190 bool zero_is_false = true; // Zero in CMPRES1 indicates a false condition.
168 switch (true_condition.rel_op()) { 191 switch (true_condition.rel_op()) {
169 case AL: return; // Result holds true_value. 192 case AL:
170 case NV: __ LoadImmediate(result, false_value); return; 193 return; // Result holds true_value.
194 case NV:
195 __ LoadImmediate(result, false_value);
196 return;
171 case EQ: 197 case EQ:
172 zero_is_false = false; 198 zero_is_false = false;
173 // fall through. 199 // fall through.
174 case NE: { 200 case NE: {
175 if (left == IMM) { 201 if (left == IMM) {
176 __ XorImmediate(CMPRES1, right, true_condition.imm()); 202 __ XorImmediate(CMPRES1, right, true_condition.imm());
177 } else if (right == IMM) { 203 } else if (right == IMM) {
178 __ XorImmediate(CMPRES1, left, true_condition.imm()); 204 __ XorImmediate(CMPRES1, left, true_condition.imm());
179 } else { 205 } else {
180 __ xor_(CMPRES1, left, right); 206 __ xor_(CMPRES1, left, right);
181 } 207 }
182 break; 208 break;
183 } 209 }
184 case GE: 210 case GE:
185 zero_is_false = false; 211 zero_is_false = false;
186 // fall through. 212 // fall through.
187 case LT: { 213 case LT: {
188 if (left == IMM) { 214 if (left == IMM) {
189 __ slti(CMPRES1, right, Immediate(true_condition.imm() + 1)); 215 __ slti(CMPRES1, right, Immediate(true_condition.imm() + 1));
190 zero_is_false = !zero_is_false; 216 zero_is_false = !zero_is_false;
191 } else if (right == IMM) { 217 } else if (right == IMM) {
192 __ slti(CMPRES1, left, Immediate(true_condition.imm())); 218 __ slti(CMPRES1, left, Immediate(true_condition.imm()));
193 } else { 219 } else {
194 __ slt(CMPRES1, left, right); 220 __ slt(CMPRES1, left, right);
195 } 221 }
196 break; 222 break;
197 } 223 }
198 case LE: 224 case LE:
199 zero_is_false = false; 225 zero_is_false = false;
200 // fall through. 226 // fall through.
201 case GT: { 227 case GT: {
202 if (left == IMM) { 228 if (left == IMM) {
203 __ slti(CMPRES1, right, Immediate(true_condition.imm())); 229 __ slti(CMPRES1, right, Immediate(true_condition.imm()));
204 } else if (right == IMM) { 230 } else if (right == IMM) {
205 __ slti(CMPRES1, left, Immediate(true_condition.imm() + 1)); 231 __ slti(CMPRES1, left, Immediate(true_condition.imm() + 1));
206 zero_is_false = !zero_is_false; 232 zero_is_false = !zero_is_false;
207 } else { 233 } else {
208 __ slt(CMPRES1, right, left); 234 __ slt(CMPRES1, right, left);
209 } 235 }
210 break; 236 break;
211 } 237 }
212 case UGE: 238 case UGE:
213 zero_is_false = false; 239 zero_is_false = false;
214 // fall through. 240 // fall through.
215 case ULT: { 241 case ULT: {
216 ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used. 242 ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used.
217 __ sltu(CMPRES1, left, right); 243 __ sltu(CMPRES1, left, right);
218 break; 244 break;
219 } 245 }
220 case ULE: 246 case ULE:
221 zero_is_false = false; 247 zero_is_false = false;
222 // fall through. 248 // fall through.
223 case UGT: { 249 case UGT: {
224 ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used. 250 ASSERT((left != IMM) && (right != IMM)); // No unsigned constants used.
225 __ sltu(CMPRES1, right, left); 251 __ sltu(CMPRES1, right, left);
226 break; 252 break;
227 } 253 }
228 default: 254 default:
229 UNREACHABLE(); 255 UNREACHABLE();
230 } 256 }
231 257
232 // CMPRES1 is the evaluated condition, zero or non-zero, as specified by the 258 // CMPRES1 is the evaluated condition, zero or non-zero, as specified by the
(...skipping 10 matching lines...) Expand all
243 } else { 269 } else {
244 __ movn(result, false_value_reg, CMPRES1); 270 __ movn(result, false_value_reg, CMPRES1);
245 } 271 }
246 } 272 }
247 273
248 274
249 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, 275 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
250 bool opt) const { 276 bool opt) const {
251 const intptr_t kNumInputs = 1; 277 const intptr_t kNumInputs = 1;
252 const intptr_t kNumTemps = 0; 278 const intptr_t kNumTemps = 0;
253 LocationSummary* summary = new(zone) LocationSummary( 279 LocationSummary* summary = new (zone)
254 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 280 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
255 summary->set_in(0, Location::RegisterLocation(T0)); // Function. 281 summary->set_in(0, Location::RegisterLocation(T0)); // Function.
256 summary->set_out(0, Location::RegisterLocation(V0)); 282 summary->set_out(0, Location::RegisterLocation(V0));
257 return summary; 283 return summary;
258 } 284 }
259 285
260 286
261 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 287 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
262 // Load arguments descriptor in S4. 288 // Load arguments descriptor in S4.
263 int argument_count = ArgumentCount(); 289 int argument_count = ArgumentCount();
264 const Array& arguments_descriptor = 290 const Array& arguments_descriptor = Array::ZoneHandle(
265 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 291 ArgumentsDescriptor::New(argument_count, argument_names()));
266 argument_names()));
267 __ LoadObject(S4, arguments_descriptor); 292 __ LoadObject(S4, arguments_descriptor);
268 293
269 // Load closure function code in T2. 294 // Load closure function code in T2.
270 // S4: arguments descriptor array. 295 // S4: arguments descriptor array.
271 // S5: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). 296 // S5: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
272 ASSERT(locs()->in(0).reg() == T0); 297 ASSERT(locs()->in(0).reg() == T0);
273 __ LoadImmediate(S5, 0); 298 __ LoadImmediate(S5, 0);
274 __ lw(T2, FieldAddress(T0, Function::entry_point_offset())); 299 __ lw(T2, FieldAddress(T0, Function::entry_point_offset()));
275 __ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); 300 __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
276 __ jalr(T2); 301 __ jalr(T2);
277 compiler->RecordSafepoint(locs()); 302 compiler->RecordSafepoint(locs());
278 // Marks either the continuation point in unoptimized code or the 303 // Marks either the continuation point in unoptimized code or the
279 // deoptimization point in optimized code, after call. 304 // deoptimization point in optimized code, after call.
280 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id()); 305 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
281 if (compiler->is_optimizing()) { 306 if (compiler->is_optimizing()) {
282 compiler->AddDeoptIndexAtCall(deopt_id_after); 307 compiler->AddDeoptIndexAtCall(deopt_id_after);
283 } 308 }
284 // Add deoptimization continuation point after the call and before the 309 // Add deoptimization continuation point after the call and before the
285 // arguments are removed. 310 // arguments are removed.
286 // In optimized code this descriptor is needed for exception handling. 311 // In optimized code this descriptor is needed for exception handling.
287 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, 312 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after,
288 deopt_id_after,
289 token_pos()); 313 token_pos());
290 __ Drop(argument_count); 314 __ Drop(argument_count);
291 } 315 }
292 316
293 317
294 LocationSummary* LoadLocalInstr::MakeLocationSummary(Zone* zone, 318 LocationSummary* LoadLocalInstr::MakeLocationSummary(Zone* zone,
295 bool opt) const { 319 bool opt) const {
296 return LocationSummary::Make(zone, 320 return LocationSummary::Make(zone, 0, Location::RequiresRegister(),
297 0,
298 Location::RequiresRegister(),
299 LocationSummary::kNoCall); 321 LocationSummary::kNoCall);
300 } 322 }
301 323
302 324
303 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 325 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
304 __ Comment("LoadLocalInstr"); 326 __ Comment("LoadLocalInstr");
305 Register result = locs()->out(0).reg(); 327 Register result = locs()->out(0).reg();
306 __ LoadFromOffset(result, FP, local().index() * kWordSize); 328 __ LoadFromOffset(result, FP, local().index() * kWordSize);
307 } 329 }
308 330
309 331
310 LocationSummary* StoreLocalInstr::MakeLocationSummary(Zone* zone, 332 LocationSummary* StoreLocalInstr::MakeLocationSummary(Zone* zone,
311 bool opt) const { 333 bool opt) const {
312 return LocationSummary::Make(zone, 334 return LocationSummary::Make(zone, 1, Location::SameAsFirstInput(),
313 1,
314 Location::SameAsFirstInput(),
315 LocationSummary::kNoCall); 335 LocationSummary::kNoCall);
316 } 336 }
317 337
318 338
319 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 339 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
320 __ Comment("StoreLocalInstr"); 340 __ Comment("StoreLocalInstr");
321 Register value = locs()->in(0).reg(); 341 Register value = locs()->in(0).reg();
322 Register result = locs()->out(0).reg(); 342 Register result = locs()->out(0).reg();
323 ASSERT(result == value); // Assert that register assignment is correct. 343 ASSERT(result == value); // Assert that register assignment is correct.
324 __ StoreToOffset(value, FP, local().index() * kWordSize); 344 __ StoreToOffset(value, FP, local().index() * kWordSize);
325 } 345 }
326 346
327 347
328 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone, 348 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone,
329 bool opt) const { 349 bool opt) const {
330 return LocationSummary::Make(zone, 350 return LocationSummary::Make(zone, 0, Location::RequiresRegister(),
331 0,
332 Location::RequiresRegister(),
333 LocationSummary::kNoCall); 351 LocationSummary::kNoCall);
334 } 352 }
335 353
336 354
337 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 355 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
338 // The register allocator drops constant definitions that have no uses. 356 // The register allocator drops constant definitions that have no uses.
339 if (!locs()->out(0).IsInvalid()) { 357 if (!locs()->out(0).IsInvalid()) {
340 __ Comment("ConstantInstr"); 358 __ Comment("ConstantInstr");
341 Register result = locs()->out(0).reg(); 359 Register result = locs()->out(0).reg();
342 __ LoadObject(result, value()); 360 __ LoadObject(result, value());
343 } 361 }
344 } 362 }
345 363
346 364
347 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Zone* zone, 365 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Zone* zone,
348 bool opt) const { 366 bool opt) const {
349 const intptr_t kNumInputs = 0; 367 const intptr_t kNumInputs = 0;
350 const intptr_t kNumTemps = (representation_ == kUnboxedInt32) ? 0 : 1; 368 const intptr_t kNumTemps = (representation_ == kUnboxedInt32) ? 0 : 1;
351 LocationSummary* locs = new(zone) LocationSummary( 369 LocationSummary* locs = new (zone)
352 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 370 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
353 if (representation_ == kUnboxedInt32) { 371 if (representation_ == kUnboxedInt32) {
354 locs->set_out(0, Location::RequiresRegister()); 372 locs->set_out(0, Location::RequiresRegister());
355 } else { 373 } else {
356 ASSERT(representation_ == kUnboxedDouble); 374 ASSERT(representation_ == kUnboxedDouble);
357 locs->set_out(0, Location::RequiresFpuRegister()); 375 locs->set_out(0, Location::RequiresFpuRegister());
358 } 376 }
359 if (kNumTemps > 0) { 377 if (kNumTemps > 0) {
360 locs->set_temp(0, Location::RequiresRegister()); 378 locs->set_temp(0, Location::RequiresRegister());
361 } 379 }
362 return locs; 380 return locs;
363 } 381 }
364 382
365 383
366 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 384 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
367 // The register allocator drops constant definitions that have no uses. 385 // The register allocator drops constant definitions that have no uses.
368 if (!locs()->out(0).IsInvalid()) { 386 if (!locs()->out(0).IsInvalid()) {
369 switch (representation_) { 387 switch (representation_) {
370 case kUnboxedDouble: { 388 case kUnboxedDouble: {
371 ASSERT(value().IsDouble()); 389 ASSERT(value().IsDouble());
372 const Register const_value = locs()->temp(0).reg(); 390 const Register const_value = locs()->temp(0).reg();
373 const DRegister result = locs()->out(0).fpu_reg(); 391 const DRegister result = locs()->out(0).fpu_reg();
374 __ LoadObject(const_value, value()); 392 __ LoadObject(const_value, value());
375 __ LoadDFromOffset(result, const_value, 393 __ LoadDFromOffset(result, const_value,
376 Double::value_offset() - kHeapObjectTag); 394 Double::value_offset() - kHeapObjectTag);
377 break; 395 break;
378 } 396 }
379 397
380 case kUnboxedInt32: 398 case kUnboxedInt32:
381 __ LoadImmediate(locs()->out(0).reg(), 399 __ LoadImmediate(locs()->out(0).reg(), Smi::Cast(value()).Value());
382 Smi::Cast(value()).Value());
383 break; 400 break;
384 401
385 default: 402 default:
386 UNREACHABLE(); 403 UNREACHABLE();
387 } 404 }
388 } 405 }
389 } 406 }
390 407
391 408
392 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, 409 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
393 bool opt) const { 410 bool opt) const {
394 const intptr_t kNumInputs = 2; 411 const intptr_t kNumInputs = 2;
395 const intptr_t kNumTemps = 0; 412 const intptr_t kNumTemps = 0;
396 LocationSummary* summary = new(zone) LocationSummary( 413 LocationSummary* summary = new (zone)
397 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 414 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
398 summary->set_in(0, Location::RegisterLocation(A0)); // Value. 415 summary->set_in(0, Location::RegisterLocation(A0)); // Value.
399 summary->set_in(1, Location::RegisterLocation(A1)); // Type arguments. 416 summary->set_in(1, Location::RegisterLocation(A1)); // Type arguments.
400 summary->set_out(0, Location::RegisterLocation(A0)); 417 summary->set_out(0, Location::RegisterLocation(A0));
401 return summary; 418 return summary;
402 } 419 }
403 420
404 421
405 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, 422 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
406 bool opt) const { 423 bool opt) const {
407 const intptr_t kNumInputs = 1; 424 const intptr_t kNumInputs = 1;
408 const intptr_t kNumTemps = 0; 425 const intptr_t kNumTemps = 0;
409 LocationSummary* locs = new(zone) LocationSummary( 426 LocationSummary* locs = new (zone)
410 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 427 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
411 locs->set_in(0, Location::RegisterLocation(A0)); 428 locs->set_in(0, Location::RegisterLocation(A0));
412 locs->set_out(0, Location::RegisterLocation(A0)); 429 locs->set_out(0, Location::RegisterLocation(A0));
413 return locs; 430 return locs;
414 } 431 }
415 432
416 433
417 static void EmitAssertBoolean(Register reg, 434 static void EmitAssertBoolean(Register reg,
418 TokenPosition token_pos, 435 TokenPosition token_pos,
419 intptr_t deopt_id, 436 intptr_t deopt_id,
420 LocationSummary* locs, 437 LocationSummary* locs,
421 FlowGraphCompiler* compiler) { 438 FlowGraphCompiler* compiler) {
422 // Check that the type of the value is allowed in conditional context. 439 // Check that the type of the value is allowed in conditional context.
423 // Call the runtime if the object is not bool::true or bool::false. 440 // Call the runtime if the object is not bool::true or bool::false.
424 ASSERT(locs->always_calls()); 441 ASSERT(locs->always_calls());
425 Label done; 442 Label done;
426 443
427 if (Isolate::Current()->type_checks()) { 444 if (Isolate::Current()->type_checks()) {
428 __ BranchEqual(reg, Bool::True(), &done); 445 __ BranchEqual(reg, Bool::True(), &done);
429 __ BranchEqual(reg, Bool::False(), &done); 446 __ BranchEqual(reg, Bool::False(), &done);
430 } else { 447 } else {
431 ASSERT(Isolate::Current()->asserts()); 448 ASSERT(Isolate::Current()->asserts());
432 __ BranchNotEqual(reg, Object::null_instance(), &done); 449 __ BranchNotEqual(reg, Object::null_instance(), &done);
433 } 450 }
434 451
435 __ Push(reg); // Push the source object. 452 __ Push(reg); // Push the source object.
436 compiler->GenerateRuntimeCall(token_pos, 453 compiler->GenerateRuntimeCall(token_pos, deopt_id,
437 deopt_id, 454 kNonBoolTypeErrorRuntimeEntry, 1, locs);
438 kNonBoolTypeErrorRuntimeEntry,
439 1,
440 locs);
441 // We should never return here. 455 // We should never return here.
442 __ break_(0); 456 __ break_(0);
443 __ Bind(&done); 457 __ Bind(&done);
444 } 458 }
445 459
446 460
447 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 461 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
448 Register obj = locs()->in(0).reg(); 462 Register obj = locs()->in(0).reg();
449 Register result = locs()->out(0).reg(); 463 Register result = locs()->out(0).reg();
450 464
451 __ Comment("AssertBooleanInstr"); 465 __ Comment("AssertBooleanInstr");
452 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 466 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
453 ASSERT(obj == result); 467 ASSERT(obj == result);
454 } 468 }
455 469
456 470
457 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Zone* zone, 471 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Zone* zone,
458 bool opt) const { 472 bool opt) const {
459 const intptr_t kNumInputs = 2; 473 const intptr_t kNumInputs = 2;
460 if (operation_cid() == kMintCid) { 474 if (operation_cid() == kMintCid) {
461 const intptr_t kNumTemps = 0; 475 const intptr_t kNumTemps = 0;
462 LocationSummary* locs = new(zone) LocationSummary( 476 LocationSummary* locs = new (zone)
463 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 477 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
464 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 478 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
465 Location::RequiresRegister())); 479 Location::RequiresRegister()));
466 locs->set_in(1, Location::Pair(Location::RequiresRegister(), 480 locs->set_in(1, Location::Pair(Location::RequiresRegister(),
467 Location::RequiresRegister())); 481 Location::RequiresRegister()));
468 locs->set_out(0, Location::RequiresRegister()); 482 locs->set_out(0, Location::RequiresRegister());
469 return locs; 483 return locs;
470 } 484 }
471 if (operation_cid() == kDoubleCid) { 485 if (operation_cid() == kDoubleCid) {
472 const intptr_t kNumTemps = 0; 486 const intptr_t kNumTemps = 0;
473 LocationSummary* locs = new(zone) LocationSummary( 487 LocationSummary* locs = new (zone)
474 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 488 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
475 locs->set_in(0, Location::RequiresFpuRegister()); 489 locs->set_in(0, Location::RequiresFpuRegister());
476 locs->set_in(1, Location::RequiresFpuRegister()); 490 locs->set_in(1, Location::RequiresFpuRegister());
477 locs->set_out(0, Location::RequiresRegister()); 491 locs->set_out(0, Location::RequiresRegister());
478 return locs; 492 return locs;
479 } 493 }
480 if (operation_cid() == kSmiCid) { 494 if (operation_cid() == kSmiCid) {
481 const intptr_t kNumTemps = 0; 495 const intptr_t kNumTemps = 0;
482 LocationSummary* locs = new(zone) LocationSummary( 496 LocationSummary* locs = new (zone)
483 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 497 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
484 locs->set_in(0, Location::RegisterOrConstant(left())); 498 locs->set_in(0, Location::RegisterOrConstant(left()));
485 // Only one input can be a constant operand. The case of two constant 499 // Only one input can be a constant operand. The case of two constant
486 // operands should be handled by constant propagation. 500 // operands should be handled by constant propagation.
487 locs->set_in(1, locs->in(0).IsConstant() 501 locs->set_in(1, locs->in(0).IsConstant()
488 ? Location::RequiresRegister() 502 ? Location::RequiresRegister()
489 : Location::RegisterOrConstant(right())); 503 : Location::RegisterOrConstant(right()));
490 locs->set_out(0, Location::RequiresRegister()); 504 locs->set_out(0, Location::RequiresRegister());
491 return locs; 505 return locs;
492 } 506 }
493 UNREACHABLE(); 507 UNREACHABLE();
(...skipping 16 matching lines...) Expand all
510 } else { 524 } else {
511 __ beq(CMPRES1, ZR, value_is_smi); 525 __ beq(CMPRES1, ZR, value_is_smi);
512 } 526 }
513 __ LoadClassId(value_cid_reg, value_reg); 527 __ LoadClassId(value_cid_reg, value_reg);
514 __ Bind(&done); 528 __ Bind(&done);
515 } 529 }
516 530
517 531
518 static RelationOperator TokenKindToIntRelOp(Token::Kind kind) { 532 static RelationOperator TokenKindToIntRelOp(Token::Kind kind) {
519 switch (kind) { 533 switch (kind) {
520 case Token::kEQ: return EQ; 534 case Token::kEQ:
521 case Token::kNE: return NE; 535 return EQ;
522 case Token::kLT: return LT; 536 case Token::kNE:
523 case Token::kGT: return GT; 537 return NE;
524 case Token::kLTE: return LE; 538 case Token::kLT:
525 case Token::kGTE: return GE; 539 return LT;
540 case Token::kGT:
541 return GT;
542 case Token::kLTE:
543 return LE;
544 case Token::kGTE:
545 return GE;
526 default: 546 default:
527 UNREACHABLE(); 547 UNREACHABLE();
528 return NV; 548 return NV;
529 } 549 }
530 } 550 }
531 551
532 552
533 static RelationOperator TokenKindToUintRelOp(Token::Kind kind) { 553 static RelationOperator TokenKindToUintRelOp(Token::Kind kind) {
534 switch (kind) { 554 switch (kind) {
535 case Token::kEQ: return EQ; 555 case Token::kEQ:
536 case Token::kNE: return NE; 556 return EQ;
537 case Token::kLT: return ULT; 557 case Token::kNE:
538 case Token::kGT: return UGT; 558 return NE;
539 case Token::kLTE: return ULE; 559 case Token::kLT:
540 case Token::kGTE: return UGE; 560 return ULT;
561 case Token::kGT:
562 return UGT;
563 case Token::kLTE:
564 return ULE;
565 case Token::kGTE:
566 return UGE;
541 default: 567 default:
542 UNREACHABLE(); 568 UNREACHABLE();
543 return NV; 569 return NV;
544 } 570 }
545 } 571 }
546 572
547 573
548 // The comparison code to emit is specified by true_condition. 574 // The comparison code to emit is specified by true_condition.
549 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 575 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
550 Condition true_condition, 576 Condition true_condition,
(...skipping 18 matching lines...) Expand all
569 const LocationSummary& locs, 595 const LocationSummary& locs,
570 Token::Kind kind) { 596 Token::Kind kind) {
571 __ Comment("EmitSmiComparisonOp"); 597 __ Comment("EmitSmiComparisonOp");
572 const Location left = locs.in(0); 598 const Location left = locs.in(0);
573 const Location right = locs.in(1); 599 const Location right = locs.in(1);
574 ASSERT(!left.IsConstant() || !right.IsConstant()); 600 ASSERT(!left.IsConstant() || !right.IsConstant());
575 ASSERT(left.IsRegister() || left.IsConstant()); 601 ASSERT(left.IsRegister() || left.IsConstant());
576 ASSERT(right.IsRegister() || right.IsConstant()); 602 ASSERT(right.IsRegister() || right.IsConstant());
577 603
578 int16_t imm = 0; 604 int16_t imm = 0;
579 const Register left_reg = left.IsRegister() ? 605 const Register left_reg =
580 left.reg() : __ LoadConditionOperand(CMPRES1, left.constant(), &imm); 606 left.IsRegister() ? left.reg() : __ LoadConditionOperand(
581 const Register right_reg = right.IsRegister() ? 607 CMPRES1, left.constant(), &imm);
582 right.reg() : __ LoadConditionOperand(CMPRES2, right.constant(), &imm); 608 const Register right_reg =
609 right.IsRegister() ? right.reg() : __ LoadConditionOperand(
610 CMPRES2, right.constant(), &imm);
583 return Condition(left_reg, right_reg, TokenKindToIntRelOp(kind), imm); 611 return Condition(left_reg, right_reg, TokenKindToIntRelOp(kind), imm);
584 } 612 }
585 613
586 614
587 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 615 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
588 const LocationSummary& locs, 616 const LocationSummary& locs,
589 Token::Kind kind, 617 Token::Kind kind,
590 BranchLabels labels) { 618 BranchLabels labels) {
591 __ Comment("EmitUnboxedMintEqualityOp"); 619 __ Comment("EmitUnboxedMintEqualityOp");
592 ASSERT(Token::IsEqualityOperator(kind)); 620 ASSERT(Token::IsEqualityOperator(kind));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 698 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
671 const LocationSummary& locs, 699 const LocationSummary& locs,
672 Token::Kind kind, 700 Token::Kind kind,
673 BranchLabels labels) { 701 BranchLabels labels) {
674 DRegister left = locs.in(0).fpu_reg(); 702 DRegister left = locs.in(0).fpu_reg();
675 DRegister right = locs.in(1).fpu_reg(); 703 DRegister right = locs.in(1).fpu_reg();
676 704
677 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right); 705 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right);
678 706
679 __ cund(left, right); 707 __ cund(left, right);
680 Label* nan_label = (kind == Token::kNE) 708 Label* nan_label =
681 ? labels.true_label : labels.false_label; 709 (kind == Token::kNE) ? labels.true_label : labels.false_label;
682 __ bc1t(nan_label); 710 __ bc1t(nan_label);
683 711
684 switch (kind) { 712 switch (kind) {
685 case Token::kEQ: __ ceqd(left, right); break; 713 case Token::kEQ:
686 case Token::kNE: __ ceqd(left, right); break; 714 __ ceqd(left, right);
687 case Token::kLT: __ coltd(left, right); break; 715 break;
688 case Token::kLTE: __ coled(left, right); break; 716 case Token::kNE:
689 case Token::kGT: __ coltd(right, left); break; 717 __ ceqd(left, right);
690 case Token::kGTE: __ coled(right, left); break; 718 break;
719 case Token::kLT:
720 __ coltd(left, right);
721 break;
722 case Token::kLTE:
723 __ coled(left, right);
724 break;
725 case Token::kGT:
726 __ coltd(right, left);
727 break;
728 case Token::kGTE:
729 __ coled(right, left);
730 break;
691 default: { 731 default: {
692 // We should only be passing the above conditions to this function. 732 // We should only be passing the above conditions to this function.
693 UNREACHABLE(); 733 UNREACHABLE();
694 break; 734 break;
695 } 735 }
696 } 736 }
697 737
698 if (labels.false_label == NULL) { 738 if (labels.false_label == NULL) {
699 // Generate branch-free code and return result in condition. 739 // Generate branch-free code and return result in condition.
700 __ LoadImmediate(CMPRES1, 1); 740 __ LoadImmediate(CMPRES1, 1);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 777 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
738 } 778 }
739 } 779 }
740 780
741 781
742 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 782 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
743 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 783 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
744 __ Comment("EqualityCompareInstr"); 784 __ Comment("EqualityCompareInstr");
745 785
746 Label is_true, is_false; 786 Label is_true, is_false;
747 BranchLabels labels = { &is_true, &is_false, &is_false }; 787 BranchLabels labels = {&is_true, &is_false, &is_false};
748 Condition true_condition = EmitComparisonCode(compiler, labels); 788 Condition true_condition = EmitComparisonCode(compiler, labels);
749 EmitBranchOnCondition(compiler, true_condition, labels); 789 EmitBranchOnCondition(compiler, true_condition, labels);
750 790
751 Register result = locs()->out(0).reg(); 791 Register result = locs()->out(0).reg();
752 Label done; 792 Label done;
753 __ Bind(&is_false); 793 __ Bind(&is_false);
754 __ LoadObject(result, Bool::False()); 794 __ LoadObject(result, Bool::False());
755 __ b(&done); 795 __ b(&done);
756 __ Bind(&is_true); 796 __ Bind(&is_true);
757 __ LoadObject(result, Bool::True()); 797 __ LoadObject(result, Bool::True());
758 __ Bind(&done); 798 __ Bind(&done);
759 } 799 }
760 800
761 801
762 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 802 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
763 BranchInstr* branch) { 803 BranchInstr* branch) {
764 __ Comment("EqualityCompareInstr::EmitBranchCode"); 804 __ Comment("EqualityCompareInstr::EmitBranchCode");
765 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 805 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
766 806
767 BranchLabels labels = compiler->CreateBranchLabels(branch); 807 BranchLabels labels = compiler->CreateBranchLabels(branch);
768 Condition true_condition = EmitComparisonCode(compiler, labels); 808 Condition true_condition = EmitComparisonCode(compiler, labels);
769 EmitBranchOnCondition(compiler, true_condition, labels); 809 EmitBranchOnCondition(compiler, true_condition, labels);
770 } 810 }
771 811
772 812
773 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, 813 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
774 bool opt) const {
775 const intptr_t kNumInputs = 2; 814 const intptr_t kNumInputs = 2;
776 const intptr_t kNumTemps = 0; 815 const intptr_t kNumTemps = 0;
777 LocationSummary* locs = new(zone) LocationSummary( 816 LocationSummary* locs = new (zone)
778 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 817 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
779 locs->set_in(0, Location::RequiresRegister()); 818 locs->set_in(0, Location::RequiresRegister());
780 // Only one input can be a constant operand. The case of two constant 819 // Only one input can be a constant operand. The case of two constant
781 // operands should be handled by constant propagation. 820 // operands should be handled by constant propagation.
782 locs->set_in(1, Location::RegisterOrConstant(right())); 821 locs->set_in(1, Location::RegisterOrConstant(right()));
783 return locs; 822 return locs;
784 } 823 }
785 824
786 825
787 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 826 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
788 BranchLabels labels) { 827 BranchLabels labels) {
789 Register left = locs()->in(0).reg(); 828 Register left = locs()->in(0).reg();
790 Location right = locs()->in(1); 829 Location right = locs()->in(1);
791 if (right.IsConstant()) { 830 if (right.IsConstant()) {
792 ASSERT(right.constant().IsSmi()); 831 ASSERT(right.constant().IsSmi());
793 const int32_t imm = 832 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
794 reinterpret_cast<int32_t>(right.constant().raw());
795 __ AndImmediate(CMPRES1, left, imm); 833 __ AndImmediate(CMPRES1, left, imm);
796 } else { 834 } else {
797 __ and_(CMPRES1, left, right.reg()); 835 __ and_(CMPRES1, left, right.reg());
798 } 836 }
799 return Condition(CMPRES1, ZR, (kind() == Token::kNE) ? NE : EQ); 837 return Condition(CMPRES1, ZR, (kind() == Token::kNE) ? NE : EQ);
800 } 838 }
801 839
802 840
803 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 841 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
804 // Never emitted outside of the BranchInstr. 842 // Never emitted outside of the BranchInstr.
805 UNREACHABLE(); 843 UNREACHABLE();
806 } 844 }
807 845
808 846
809 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, 847 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
810 BranchInstr* branch) { 848 BranchInstr* branch) {
811 BranchLabels labels = compiler->CreateBranchLabels(branch); 849 BranchLabels labels = compiler->CreateBranchLabels(branch);
812 Condition true_condition = EmitComparisonCode(compiler, labels); 850 Condition true_condition = EmitComparisonCode(compiler, labels);
813 EmitBranchOnCondition(compiler, true_condition, labels); 851 EmitBranchOnCondition(compiler, true_condition, labels);
814 } 852 }
815 853
816 854
817 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 855 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
818 bool opt) const { 856 bool opt) const {
819 const intptr_t kNumInputs = 1; 857 const intptr_t kNumInputs = 1;
820 const intptr_t kNumTemps = 1; 858 const intptr_t kNumTemps = 1;
821 LocationSummary* locs = new(zone) LocationSummary( 859 LocationSummary* locs = new (zone)
822 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 860 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
823 locs->set_in(0, Location::RequiresRegister()); 861 locs->set_in(0, Location::RequiresRegister());
824 locs->set_temp(0, Location::RequiresRegister()); 862 locs->set_temp(0, Location::RequiresRegister());
825 locs->set_out(0, Location::RequiresRegister()); 863 locs->set_out(0, Location::RequiresRegister());
826 return locs; 864 return locs;
827 } 865 }
828 866
829 867
830 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 868 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
831 BranchLabels labels) { 869 BranchLabels labels) {
832 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); 870 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
833 Register val_reg = locs()->in(0).reg(); 871 Register val_reg = locs()->in(0).reg();
834 Register cid_reg = locs()->temp(0).reg(); 872 Register cid_reg = locs()->temp(0).reg();
835 873
836 Label* deopt = CanDeoptimize() 874 Label* deopt =
837 ? compiler->AddDeoptStub(deopt_id(), 875 CanDeoptimize()
838 ICData::kDeoptTestCids, 876 ? compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids,
839 licm_hoisted_ ? ICData::kHoisted : 0) 877 licm_hoisted_ ? ICData::kHoisted : 0)
840 : NULL; 878 : NULL;
841 879
842 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; 880 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
843 const ZoneGrowableArray<intptr_t>& data = cid_results(); 881 const ZoneGrowableArray<intptr_t>& data = cid_results();
844 ASSERT(data[0] == kSmiCid); 882 ASSERT(data[0] == kSmiCid);
845 bool result = data[1] == true_result; 883 bool result = data[1] == true_result;
846 __ andi(CMPRES1, val_reg, Immediate(kSmiTagMask)); 884 __ andi(CMPRES1, val_reg, Immediate(kSmiTagMask));
847 __ beq(CMPRES1, ZR, result ? labels.true_label : labels.false_label); 885 __ beq(CMPRES1, ZR, result ? labels.true_label : labels.false_label);
848 886
849 __ LoadClassId(cid_reg, val_reg); 887 __ LoadClassId(cid_reg, val_reg);
850 for (intptr_t i = 2; i < data.length(); i += 2) { 888 for (intptr_t i = 2; i < data.length(); i += 2) {
(...skipping 20 matching lines...) Expand all
871 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler, 909 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
872 BranchInstr* branch) { 910 BranchInstr* branch) {
873 BranchLabels labels = compiler->CreateBranchLabels(branch); 911 BranchLabels labels = compiler->CreateBranchLabels(branch);
874 EmitComparisonCode(compiler, labels); 912 EmitComparisonCode(compiler, labels);
875 } 913 }
876 914
877 915
878 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 916 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
879 Register result_reg = locs()->out(0).reg(); 917 Register result_reg = locs()->out(0).reg();
880 Label is_true, is_false, done; 918 Label is_true, is_false, done;
881 BranchLabels labels = { &is_true, &is_false, &is_false }; 919 BranchLabels labels = {&is_true, &is_false, &is_false};
882 EmitComparisonCode(compiler, labels); 920 EmitComparisonCode(compiler, labels);
883 __ Bind(&is_false); 921 __ Bind(&is_false);
884 __ LoadObject(result_reg, Bool::False()); 922 __ LoadObject(result_reg, Bool::False());
885 __ b(&done); 923 __ b(&done);
886 __ Bind(&is_true); 924 __ Bind(&is_true);
887 __ LoadObject(result_reg, Bool::True()); 925 __ LoadObject(result_reg, Bool::True());
888 __ Bind(&done); 926 __ Bind(&done);
889 } 927 }
890 928
891 929
892 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 930 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
893 bool opt) const { 931 bool opt) const {
894 const intptr_t kNumInputs = 2; 932 const intptr_t kNumInputs = 2;
895 const intptr_t kNumTemps = 0; 933 const intptr_t kNumTemps = 0;
896 if (operation_cid() == kMintCid) { 934 if (operation_cid() == kMintCid) {
897 const intptr_t kNumTemps = 0; 935 const intptr_t kNumTemps = 0;
898 LocationSummary* locs = new(zone) LocationSummary( 936 LocationSummary* locs = new (zone)
899 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 937 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
900 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 938 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
901 Location::RequiresRegister())); 939 Location::RequiresRegister()));
902 locs->set_in(1, Location::Pair(Location::RequiresRegister(), 940 locs->set_in(1, Location::Pair(Location::RequiresRegister(),
903 Location::RequiresRegister())); 941 Location::RequiresRegister()));
904 locs->set_out(0, Location::RequiresRegister()); 942 locs->set_out(0, Location::RequiresRegister());
905 return locs; 943 return locs;
906 } 944 }
907 if (operation_cid() == kDoubleCid) { 945 if (operation_cid() == kDoubleCid) {
908 LocationSummary* summary = new(zone) LocationSummary( 946 LocationSummary* summary = new (zone)
909 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 947 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
910 summary->set_in(0, Location::RequiresFpuRegister()); 948 summary->set_in(0, Location::RequiresFpuRegister());
911 summary->set_in(1, Location::RequiresFpuRegister()); 949 summary->set_in(1, Location::RequiresFpuRegister());
912 summary->set_out(0, Location::RequiresRegister()); 950 summary->set_out(0, Location::RequiresRegister());
913 return summary; 951 return summary;
914 } 952 }
915 ASSERT(operation_cid() == kSmiCid); 953 ASSERT(operation_cid() == kSmiCid);
916 LocationSummary* summary = new(zone) LocationSummary( 954 LocationSummary* summary = new (zone)
917 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 955 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
918 summary->set_in(0, Location::RegisterOrConstant(left())); 956 summary->set_in(0, Location::RegisterOrConstant(left()));
919 // Only one input can be a constant operand. The case of two constant 957 // Only one input can be a constant operand. The case of two constant
920 // operands should be handled by constant propagation. 958 // operands should be handled by constant propagation.
921 summary->set_in(1, summary->in(0).IsConstant() 959 summary->set_in(1, summary->in(0).IsConstant()
922 ? Location::RequiresRegister() 960 ? Location::RequiresRegister()
923 : Location::RegisterOrConstant(right())); 961 : Location::RegisterOrConstant(right()));
924 summary->set_out(0, Location::RequiresRegister()); 962 summary->set_out(0, Location::RequiresRegister());
925 return summary; 963 return summary;
926 } 964 }
927 965
928 966
929 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 967 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
930 BranchLabels labels) { 968 BranchLabels labels) {
931 if (operation_cid() == kSmiCid) { 969 if (operation_cid() == kSmiCid) {
932 return EmitSmiComparisonOp(compiler, *locs(), kind()); 970 return EmitSmiComparisonOp(compiler, *locs(), kind());
933 } else if (operation_cid() == kMintCid) { 971 } else if (operation_cid() == kMintCid) {
934 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); 972 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
935 } else { 973 } else {
936 ASSERT(operation_cid() == kDoubleCid); 974 ASSERT(operation_cid() == kDoubleCid);
937 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 975 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
938 } 976 }
939 } 977 }
940 978
941 979
942 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 980 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
943 __ Comment("RelationalOpInstr"); 981 __ Comment("RelationalOpInstr");
944 982
945 Label is_true, is_false; 983 Label is_true, is_false;
946 BranchLabels labels = { &is_true, &is_false, &is_false }; 984 BranchLabels labels = {&is_true, &is_false, &is_false};
947 Condition true_condition = EmitComparisonCode(compiler, labels); 985 Condition true_condition = EmitComparisonCode(compiler, labels);
948 EmitBranchOnCondition(compiler, true_condition, labels); 986 EmitBranchOnCondition(compiler, true_condition, labels);
949 987
950 Register result = locs()->out(0).reg(); 988 Register result = locs()->out(0).reg();
951 Label done; 989 Label done;
952 __ Bind(&is_false); 990 __ Bind(&is_false);
953 __ LoadObject(result, Bool::False()); 991 __ LoadObject(result, Bool::False());
954 __ b(&done); 992 __ b(&done);
955 __ Bind(&is_true); 993 __ Bind(&is_true);
956 __ LoadObject(result, Bool::True()); 994 __ LoadObject(result, Bool::True());
(...skipping 19 matching lines...) Expand all
976 1014
977 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1015 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
978 SetupNative(); 1016 SetupNative();
979 __ Comment("NativeCallInstr"); 1017 __ Comment("NativeCallInstr");
980 Register result = locs()->out(0).reg(); 1018 Register result = locs()->out(0).reg();
981 1019
982 // Push the result place holder initialized to NULL. 1020 // Push the result place holder initialized to NULL.
983 __ PushObject(Object::null_object()); 1021 __ PushObject(Object::null_object());
984 // Pass a pointer to the first argument in A2. 1022 // Pass a pointer to the first argument in A2.
985 if (!function().HasOptionalParameters()) { 1023 if (!function().HasOptionalParameters()) {
986 __ AddImmediate(A2, FP, (kParamEndSlotFromFp + 1024 __ AddImmediate(
987 function().NumParameters()) * kWordSize); 1025 A2, FP, (kParamEndSlotFromFp + function().NumParameters()) * kWordSize);
988 } else { 1026 } else {
989 __ AddImmediate(A2, FP, kFirstLocalSlotFromFp * kWordSize); 1027 __ AddImmediate(A2, FP, kFirstLocalSlotFromFp * kWordSize);
990 } 1028 }
991 // Compute the effective address. When running under the simulator, 1029 // Compute the effective address. When running under the simulator,
992 // this is a redirection address that forces the simulator to call 1030 // this is a redirection address that forces the simulator to call
993 // into the runtime system. 1031 // into the runtime system.
994 uword entry; 1032 uword entry;
995 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); 1033 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
996 const StubEntry* stub_entry; 1034 const StubEntry* stub_entry;
997 if (link_lazily()) { 1035 if (link_lazily()) {
(...skipping 10 matching lines...) Expand all
1008 } else { 1046 } else {
1009 // In the case of non bootstrap native methods the CallNativeCFunction 1047 // In the case of non bootstrap native methods the CallNativeCFunction
1010 // stub generates the redirection address when running under the simulator 1048 // stub generates the redirection address when running under the simulator
1011 // and hence we do not change 'entry' here. 1049 // and hence we do not change 'entry' here.
1012 stub_entry = StubCode::CallNativeCFunction_entry(); 1050 stub_entry = StubCode::CallNativeCFunction_entry();
1013 } 1051 }
1014 } 1052 }
1015 __ LoadImmediate(A1, argc_tag); 1053 __ LoadImmediate(A1, argc_tag);
1016 ExternalLabel label(entry); 1054 ExternalLabel label(entry);
1017 __ LoadNativeEntry(T5, &label, kNotPatchable); 1055 __ LoadNativeEntry(T5, &label, kNotPatchable);
1018 compiler->GenerateCall(token_pos(), 1056 compiler->GenerateCall(token_pos(), *stub_entry, RawPcDescriptors::kOther,
1019 *stub_entry,
1020 RawPcDescriptors::kOther,
1021 locs()); 1057 locs());
1022 __ Pop(result); 1058 __ Pop(result);
1023 } 1059 }
1024 1060
1025 1061
1026 LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary( 1062 LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
1027 Zone* zone, bool opt) const { 1063 Zone* zone,
1064 bool opt) const {
1028 const intptr_t kNumInputs = 1; 1065 const intptr_t kNumInputs = 1;
1029 // TODO(fschneider): Allow immediate operands for the char code. 1066 // TODO(fschneider): Allow immediate operands for the char code.
1030 return LocationSummary::Make(zone, 1067 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
1031 kNumInputs,
1032 Location::RequiresRegister(),
1033 LocationSummary::kNoCall); 1068 LocationSummary::kNoCall);
1034 } 1069 }
1035 1070
1036 1071
1037 void OneByteStringFromCharCodeInstr::EmitNativeCode( 1072 void OneByteStringFromCharCodeInstr::EmitNativeCode(
1038 FlowGraphCompiler* compiler) { 1073 FlowGraphCompiler* compiler) {
1039 ASSERT(compiler->is_optimizing()); 1074 ASSERT(compiler->is_optimizing());
1040 Register char_code = locs()->in(0).reg(); 1075 Register char_code = locs()->in(0).reg();
1041 Register result = locs()->out(0).reg(); 1076 Register result = locs()->out(0).reg();
1042 1077
1043 __ lw(result, Address(THR, Thread::predefined_symbols_address_offset())); 1078 __ lw(result, Address(THR, Thread::predefined_symbols_address_offset()));
1044 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1079 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1045 __ sll(TMP, char_code, 1); // Char code is a smi. 1080 __ sll(TMP, char_code, 1); // Char code is a smi.
1046 __ addu(TMP, TMP, result); 1081 __ addu(TMP, TMP, result);
1047 __ lw(result, Address(TMP)); 1082 __ lw(result, Address(TMP));
1048 } 1083 }
1049 1084
1050 1085
1051 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Zone* zone, 1086 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Zone* zone,
1052 bool opt) const { 1087 bool opt) const {
1053 const intptr_t kNumInputs = 1; 1088 const intptr_t kNumInputs = 1;
1054 return LocationSummary::Make(zone, 1089 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
1055 kNumInputs,
1056 Location::RequiresRegister(),
1057 LocationSummary::kNoCall); 1090 LocationSummary::kNoCall);
1058 } 1091 }
1059 1092
1060 1093
1061 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1094 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1062 __ Comment("StringToCharCodeInstr"); 1095 __ Comment("StringToCharCodeInstr");
1063 1096
1064 ASSERT(cid_ == kOneByteStringCid); 1097 ASSERT(cid_ == kOneByteStringCid);
1065 Register str = locs()->in(0).reg(); 1098 Register str = locs()->in(0).reg();
1066 Register result = locs()->out(0).reg(); 1099 Register result = locs()->out(0).reg();
1067 ASSERT(str != result); 1100 ASSERT(str != result);
1068 Label done; 1101 Label done;
1069 __ lw(result, FieldAddress(str, String::length_offset())); 1102 __ lw(result, FieldAddress(str, String::length_offset()));
1070 __ BranchNotEqual(result, Immediate(Smi::RawValue(1)), &done); 1103 __ BranchNotEqual(result, Immediate(Smi::RawValue(1)), &done);
1071 __ delay_slot()->addiu(result, ZR, Immediate(Smi::RawValue(-1))); 1104 __ delay_slot()->addiu(result, ZR, Immediate(Smi::RawValue(-1)));
1072 __ lbu(result, FieldAddress(str, OneByteString::data_offset())); 1105 __ lbu(result, FieldAddress(str, OneByteString::data_offset()));
1073 __ SmiTag(result); 1106 __ SmiTag(result);
1074 __ Bind(&done); 1107 __ Bind(&done);
1075 } 1108 }
1076 1109
1077 1110
1078 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Zone* zone, 1111 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Zone* zone,
1079 bool opt) const { 1112 bool opt) const {
1080 const intptr_t kNumInputs = 1; 1113 const intptr_t kNumInputs = 1;
1081 const intptr_t kNumTemps = 0; 1114 const intptr_t kNumTemps = 0;
1082 LocationSummary* summary = new(zone) LocationSummary( 1115 LocationSummary* summary = new (zone)
1083 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 1116 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
1084 summary->set_in(0, Location::RegisterLocation(A0)); 1117 summary->set_in(0, Location::RegisterLocation(A0));
1085 summary->set_out(0, Location::RegisterLocation(V0)); 1118 summary->set_out(0, Location::RegisterLocation(V0));
1086 return summary; 1119 return summary;
1087 } 1120 }
1088 1121
1089 1122
1090 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1123 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1091 Register array = locs()->in(0).reg(); 1124 Register array = locs()->in(0).reg();
1092 __ Push(array); 1125 __ Push(array);
1093 const int kNumberOfArguments = 1; 1126 const int kNumberOfArguments = 1;
1094 const Array& kNoArgumentNames = Object::null_array(); 1127 const Array& kNoArgumentNames = Object::null_array();
1095 compiler->GenerateStaticCall(deopt_id(), 1128 compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(),
1096 token_pos(), 1129 kNumberOfArguments, kNoArgumentNames, locs(),
1097 CallFunction(),
1098 kNumberOfArguments,
1099 kNoArgumentNames,
1100 locs(),
1101 ICData::Handle()); 1130 ICData::Handle());
1102 ASSERT(locs()->out(0).reg() == V0); 1131 ASSERT(locs()->out(0).reg() == V0);
1103 } 1132 }
1104 1133
1105 1134
1106 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(Zone* zone, 1135 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(Zone* zone,
1107 bool opt) const { 1136 bool opt) const {
1108 const intptr_t kNumInputs = 1; 1137 const intptr_t kNumInputs = 1;
1109 return LocationSummary::Make(zone, 1138 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
1110 kNumInputs,
1111 Location::RequiresRegister(),
1112 LocationSummary::kNoCall); 1139 LocationSummary::kNoCall);
1113 } 1140 }
1114 1141
1115 1142
1116 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1143 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1117 Register obj = locs()->in(0).reg(); 1144 Register obj = locs()->in(0).reg();
1118 Register result = locs()->out(0).reg(); 1145 Register result = locs()->out(0).reg();
1119 if (object()->definition()->representation() == kUntagged) { 1146 if (object()->definition()->representation() == kUntagged) {
1120 __ LoadFromOffset(result, obj, offset()); 1147 __ LoadFromOffset(result, obj, offset());
1121 } else { 1148 } else {
1122 ASSERT(object()->definition()->representation() == kTagged); 1149 ASSERT(object()->definition()->representation() == kTagged);
1123 __ LoadFieldFromOffset(result, obj, offset()); 1150 __ LoadFieldFromOffset(result, obj, offset());
1124 } 1151 }
1125 } 1152 }
1126 1153
1127 1154
1128 LocationSummary* LoadClassIdInstr::MakeLocationSummary(Zone* zone, 1155 LocationSummary* LoadClassIdInstr::MakeLocationSummary(Zone* zone,
1129 bool opt) const { 1156 bool opt) const {
1130 const intptr_t kNumInputs = 1; 1157 const intptr_t kNumInputs = 1;
1131 return LocationSummary::Make(zone, 1158 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
1132 kNumInputs,
1133 Location::RequiresRegister(),
1134 LocationSummary::kNoCall); 1159 LocationSummary::kNoCall);
1135 } 1160 }
1136 1161
1137 1162
1138 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1163 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1139 Register object = locs()->in(0).reg(); 1164 Register object = locs()->in(0).reg();
1140 Register result = locs()->out(0).reg(); 1165 Register result = locs()->out(0).reg();
1141 const AbstractType& value_type = *this->object()->Type()->ToAbstractType(); 1166 const AbstractType& value_type = *this->object()->Type()->ToAbstractType();
1142 if (CompileType::Smi().IsAssignableTo(value_type) || 1167 if (CompileType::Smi().IsAssignableTo(value_type) ||
1143 value_type.IsTypeParameter()) { 1168 value_type.IsTypeParameter()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 } 1246 }
1222 1247
1223 1248
1224 static bool CanBeImmediateIndex(Value* value, intptr_t cid, bool is_external) { 1249 static bool CanBeImmediateIndex(Value* value, intptr_t cid, bool is_external) {
1225 ConstantInstr* constant = value->definition()->AsConstant(); 1250 ConstantInstr* constant = value->definition()->AsConstant();
1226 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) { 1251 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) {
1227 return false; 1252 return false;
1228 } 1253 }
1229 const int64_t index = Smi::Cast(constant->value()).AsInt64Value(); 1254 const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
1230 const intptr_t scale = Instance::ElementSizeFor(cid); 1255 const intptr_t scale = Instance::ElementSizeFor(cid);
1231 const int64_t offset = index * scale + 1256 const int64_t offset =
1257 index * scale +
1232 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); 1258 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
1233 if (!Utils::IsInt(32, offset)) { 1259 if (!Utils::IsInt(32, offset)) {
1234 return false; 1260 return false;
1235 } 1261 }
1236 return Address::CanHoldOffset(static_cast<int32_t>(offset)); 1262 return Address::CanHoldOffset(static_cast<int32_t>(offset));
1237 } 1263 }
1238 1264
1239 1265
1240 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, 1266 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
1241 bool opt) const { 1267 bool opt) const {
1242 const intptr_t kNumInputs = 2; 1268 const intptr_t kNumInputs = 2;
1243 const intptr_t kNumTemps = aligned() ? 0 : 1; 1269 const intptr_t kNumTemps = aligned() ? 0 : 1;
1244 LocationSummary* locs = new(zone) LocationSummary( 1270 LocationSummary* locs = new (zone)
1245 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1271 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1246 locs->set_in(0, Location::RequiresRegister()); 1272 locs->set_in(0, Location::RequiresRegister());
1247 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) { 1273 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) {
1248 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1274 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1249 } else { 1275 } else {
1250 locs->set_in(1, Location::RequiresRegister()); 1276 locs->set_in(1, Location::RequiresRegister());
1251 } 1277 }
1252 if ((representation() == kUnboxedDouble) || 1278 if ((representation() == kUnboxedDouble) ||
1253 (representation() == kUnboxedFloat32x4) || 1279 (representation() == kUnboxedFloat32x4) ||
1254 (representation() == kUnboxedInt32x4)) { 1280 (representation() == kUnboxedInt32x4)) {
1255 locs->set_out(0, Location::RequiresFpuRegister()); 1281 locs->set_out(0, Location::RequiresFpuRegister());
1256 } else { 1282 } else {
1257 locs->set_out(0, Location::RequiresRegister()); 1283 locs->set_out(0, Location::RequiresRegister());
1258 } 1284 }
1259 if (!aligned()) { 1285 if (!aligned()) {
1260 locs->set_temp(0, Location::RequiresRegister()); 1286 locs->set_temp(0, Location::RequiresRegister());
1261 } 1287 }
1262 return locs; 1288 return locs;
1263 } 1289 }
1264 1290
1265 1291
1266 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1292 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1267 __ Comment("LoadIndexedInstr"); 1293 __ Comment("LoadIndexedInstr");
1268 // The array register points to the backing store for external arrays. 1294 // The array register points to the backing store for external arrays.
1269 const Register array = locs()->in(0).reg(); 1295 const Register array = locs()->in(0).reg();
1270 const Location index = locs()->in(1); 1296 const Location index = locs()->in(1);
1271 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg(); 1297 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
1272 1298
1273 Address element_address(kNoRegister); 1299 Address element_address(kNoRegister);
1274 if (aligned()) { 1300 if (aligned()) {
1275 element_address = index.IsRegister() 1301 element_address =
1276 ? __ ElementAddressForRegIndex(true, // Load. 1302 index.IsRegister()
1277 IsExternal(), class_id(), index_scale(), 1303 ? __ ElementAddressForRegIndex(true, // Load.
1278 array, index.reg()) 1304 IsExternal(), class_id(),
1279 : __ ElementAddressForIntIndex( 1305 index_scale(), array, index.reg())
1280 IsExternal(), class_id(), index_scale(), 1306 : __ ElementAddressForIntIndex(IsExternal(), class_id(),
1281 array, Smi::Cast(index.constant()).Value()); 1307 index_scale(), array,
1308 Smi::Cast(index.constant()).Value());
1282 // Warning: element_address may use register TMP as base. 1309 // Warning: element_address may use register TMP as base.
1283 } else { 1310 } else {
1284 if (index.IsRegister()) { 1311 if (index.IsRegister()) {
1285 __ LoadElementAddressForRegIndex(address, 1312 __ LoadElementAddressForRegIndex(address,
1286 true, // Load. 1313 true, // Load.
1287 IsExternal(), class_id(), index_scale(), 1314 IsExternal(), class_id(), index_scale(),
1288 array, index.reg()); 1315 array, index.reg());
1289 } else { 1316 } else {
1290 __ LoadElementAddressForIntIndex(address, 1317 __ LoadElementAddressForIntIndex(address, IsExternal(), class_id(),
1291 IsExternal(), class_id(), index_scale(), 1318 index_scale(), array,
1292 array,
1293 Smi::Cast(index.constant()).Value()); 1319 Smi::Cast(index.constant()).Value());
1294 } 1320 }
1295 } 1321 }
1296 1322
1297 if ((representation() == kUnboxedDouble) || 1323 if ((representation() == kUnboxedDouble) ||
1298 (representation() == kUnboxedFloat32x4) || 1324 (representation() == kUnboxedFloat32x4) ||
1299 (representation() == kUnboxedInt32x4)) { 1325 (representation() == kUnboxedInt32x4)) {
1300 DRegister result = locs()->out(0).fpu_reg(); 1326 DRegister result = locs()->out(0).fpu_reg();
1301 switch (class_id()) { 1327 switch (class_id()) {
1302 case kTypedDataFloat32ArrayCid: 1328 case kTypedDataFloat32ArrayCid:
1303 // Load single precision float. 1329 // Load single precision float.
1304 __ lwc1(EvenFRegisterOf(result), element_address); 1330 __ lwc1(EvenFRegisterOf(result), element_address);
1305 break; 1331 break;
1306 case kTypedDataFloat64ArrayCid: 1332 case kTypedDataFloat64ArrayCid:
1307 __ LoadDFromOffset(result, 1333 __ LoadDFromOffset(result, element_address.base(),
1308 element_address.base(), element_address.offset()); 1334 element_address.offset());
1309 break; 1335 break;
1310 case kTypedDataInt32x4ArrayCid: 1336 case kTypedDataInt32x4ArrayCid:
1311 case kTypedDataFloat32x4ArrayCid: 1337 case kTypedDataFloat32x4ArrayCid:
1312 UNIMPLEMENTED(); 1338 UNIMPLEMENTED();
1313 break; 1339 break;
1314 } 1340 }
1315 return; 1341 return;
1316 } 1342 }
1317 1343
1318 if ((representation() == kUnboxedUint32) || 1344 if ((representation() == kUnboxedUint32) ||
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 __ lw(result, element_address); 1410 __ lw(result, element_address);
1385 break; 1411 break;
1386 } 1412 }
1387 } 1413 }
1388 1414
1389 1415
1390 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone, 1416 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone,
1391 bool opt) const { 1417 bool opt) const {
1392 const intptr_t kNumInputs = 2; 1418 const intptr_t kNumInputs = 2;
1393 const intptr_t kNumTemps = 0; 1419 const intptr_t kNumTemps = 0;
1394 LocationSummary* summary = new(zone) LocationSummary( 1420 LocationSummary* summary = new (zone)
1395 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1421 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1396 summary->set_in(0, Location::RequiresRegister()); 1422 summary->set_in(0, Location::RequiresRegister());
1397 summary->set_in(1, Location::RequiresRegister()); 1423 summary->set_in(1, Location::RequiresRegister());
1398 1424
1399 // TODO(zerny): Handle mints properly once possible. 1425 // TODO(zerny): Handle mints properly once possible.
1400 ASSERT(representation() == kTagged); 1426 ASSERT(representation() == kTagged);
1401 summary->set_out(0, Location::RequiresRegister()); 1427 summary->set_out(0, Location::RequiresRegister());
1402 1428
1403 return summary; 1429 return summary;
1404 } 1430 }
1405 1431
1406 1432
1407 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1433 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1408 // The string register points to the backing store for external strings. 1434 // The string register points to the backing store for external strings.
1409 const Register str = locs()->in(0).reg(); 1435 const Register str = locs()->in(0).reg();
1410 const Location index = locs()->in(1); 1436 const Location index = locs()->in(1);
1411 1437
1412 Address element_address = __ ElementAddressForRegIndex( 1438 Address element_address = __ ElementAddressForRegIndex(
1413 true, IsExternal(), class_id(), index_scale(), str, index.reg()); 1439 true, IsExternal(), class_id(), index_scale(), str, index.reg());
1414 // Warning: element_address may use register TMP as base. 1440 // Warning: element_address may use register TMP as base.
1415 1441
1416 ASSERT(representation() == kTagged); 1442 ASSERT(representation() == kTagged);
1417 Register result = locs()->out(0).reg(); 1443 Register result = locs()->out(0).reg();
1418 switch (class_id()) { 1444 switch (class_id()) {
1419 case kOneByteStringCid: 1445 case kOneByteStringCid:
1420 case kExternalOneByteStringCid: 1446 case kExternalOneByteStringCid:
1421 switch (element_count()) { 1447 switch (element_count()) {
1422 case 1: __ lbu(result, element_address); break; 1448 case 1:
1423 case 2: __ lhu(result, element_address); break; 1449 __ lbu(result, element_address);
1450 break;
1451 case 2:
1452 __ lhu(result, element_address);
1453 break;
1424 case 4: // Loading multiple code units is disabled on MIPS. 1454 case 4: // Loading multiple code units is disabled on MIPS.
1425 default: UNREACHABLE(); 1455 default:
1456 UNREACHABLE();
1426 } 1457 }
1427 __ SmiTag(result); 1458 __ SmiTag(result);
1428 break; 1459 break;
1429 case kTwoByteStringCid: 1460 case kTwoByteStringCid:
1430 case kExternalTwoByteStringCid: 1461 case kExternalTwoByteStringCid:
1431 switch (element_count()) { 1462 switch (element_count()) {
1432 case 1: __ lhu(result, element_address); break; 1463 case 1:
1464 __ lhu(result, element_address);
1465 break;
1433 case 2: // Loading multiple code units is disabled on MIPS. 1466 case 2: // Loading multiple code units is disabled on MIPS.
1434 default: UNREACHABLE(); 1467 default:
1468 UNREACHABLE();
1435 } 1469 }
1436 __ SmiTag(result); 1470 __ SmiTag(result);
1437 break; 1471 break;
1438 default: 1472 default:
1439 UNREACHABLE(); 1473 UNREACHABLE();
1440 break; 1474 break;
1441 } 1475 }
1442 } 1476 }
1443 1477
1444 1478
1445 Representation StoreIndexedInstr::RequiredInputRepresentation( 1479 Representation StoreIndexedInstr::RequiredInputRepresentation(
1446 intptr_t idx) const { 1480 intptr_t idx) const {
1447 // Array can be a Dart object or a pointer to external data. 1481 // Array can be a Dart object or a pointer to external data.
1448 if (idx == 0) return kNoRepresentation; // Flexible input representation. 1482 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1449 if (idx == 1) return kTagged; // Index is a smi. 1483 if (idx == 1) return kTagged; // Index is a smi.
1450 ASSERT(idx == 2); 1484 ASSERT(idx == 2);
1451 switch (class_id_) { 1485 switch (class_id_) {
1452 case kArrayCid: 1486 case kArrayCid:
1453 case kOneByteStringCid: 1487 case kOneByteStringCid:
1454 case kTypedDataInt8ArrayCid: 1488 case kTypedDataInt8ArrayCid:
1455 case kTypedDataUint8ArrayCid: 1489 case kTypedDataUint8ArrayCid:
1456 case kExternalTypedDataUint8ArrayCid: 1490 case kExternalTypedDataUint8ArrayCid:
1457 case kTypedDataUint8ClampedArrayCid: 1491 case kTypedDataUint8ClampedArrayCid:
1458 case kExternalTypedDataUint8ClampedArrayCid: 1492 case kExternalTypedDataUint8ClampedArrayCid:
1459 case kTypedDataInt16ArrayCid: 1493 case kTypedDataInt16ArrayCid:
(...skipping 14 matching lines...) Expand all
1474 UNIMPLEMENTED(); 1508 UNIMPLEMENTED();
1475 return kTagged; 1509 return kTagged;
1476 } 1510 }
1477 } 1511 }
1478 1512
1479 1513
1480 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, 1514 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
1481 bool opt) const { 1515 bool opt) const {
1482 const intptr_t kNumInputs = 3; 1516 const intptr_t kNumInputs = 3;
1483 const intptr_t kNumTemps = aligned() ? 0 : 2; 1517 const intptr_t kNumTemps = aligned() ? 0 : 2;
1484 LocationSummary* locs = new(zone) LocationSummary( 1518 LocationSummary* locs = new (zone)
1485 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1519 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1486 locs->set_in(0, Location::RequiresRegister()); 1520 locs->set_in(0, Location::RequiresRegister());
1487 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) { 1521 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) {
1488 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1522 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1489 } else { 1523 } else {
1490 locs->set_in(1, Location::WritableRegister()); 1524 locs->set_in(1, Location::WritableRegister());
1491 } 1525 }
1492 switch (class_id()) { 1526 switch (class_id()) {
1493 case kArrayCid: 1527 case kArrayCid:
1494 locs->set_in(2, ShouldEmitStoreBarrier() 1528 locs->set_in(2, ShouldEmitStoreBarrier()
1495 ? Location::WritableRegister() 1529 ? Location::WritableRegister()
1496 : Location::RegisterOrConstant(value())); 1530 : Location::RegisterOrConstant(value()));
1497 break; 1531 break;
1498 case kExternalTypedDataUint8ArrayCid: 1532 case kExternalTypedDataUint8ArrayCid:
1499 case kExternalTypedDataUint8ClampedArrayCid: 1533 case kExternalTypedDataUint8ClampedArrayCid:
1500 case kTypedDataInt8ArrayCid: 1534 case kTypedDataInt8ArrayCid:
1501 case kTypedDataUint8ArrayCid: 1535 case kTypedDataUint8ArrayCid:
1502 case kTypedDataUint8ClampedArrayCid: 1536 case kTypedDataUint8ClampedArrayCid:
1503 case kOneByteStringCid: 1537 case kOneByteStringCid:
1504 case kTypedDataInt16ArrayCid: 1538 case kTypedDataInt16ArrayCid:
1505 case kTypedDataUint16ArrayCid: 1539 case kTypedDataUint16ArrayCid:
1506 case kTypedDataInt32ArrayCid: 1540 case kTypedDataInt32ArrayCid:
(...skipping 21 matching lines...) Expand all
1528 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1562 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1529 __ Comment("StoreIndexedInstr"); 1563 __ Comment("StoreIndexedInstr");
1530 // The array register points to the backing store for external arrays. 1564 // The array register points to the backing store for external arrays.
1531 const Register array = locs()->in(0).reg(); 1565 const Register array = locs()->in(0).reg();
1532 const Location index = locs()->in(1); 1566 const Location index = locs()->in(1);
1533 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg(); 1567 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
1534 const Register scratch = aligned() ? kNoRegister : locs()->temp(1).reg(); 1568 const Register scratch = aligned() ? kNoRegister : locs()->temp(1).reg();
1535 1569
1536 Address element_address(kNoRegister); 1570 Address element_address(kNoRegister);
1537 if (aligned()) { 1571 if (aligned()) {
1538 element_address = index.IsRegister() 1572 element_address =
1539 ? __ ElementAddressForRegIndex(false, // Store. 1573 index.IsRegister()
1540 IsExternal(), class_id(), index_scale(), 1574 ? __ ElementAddressForRegIndex(false, // Store.
1541 array, index.reg()) 1575 IsExternal(), class_id(),
1542 : __ ElementAddressForIntIndex( 1576 index_scale(), array, index.reg())
1543 IsExternal(), class_id(), index_scale(), 1577 : __ ElementAddressForIntIndex(IsExternal(), class_id(),
1544 array, Smi::Cast(index.constant()).Value()); 1578 index_scale(), array,
1579 Smi::Cast(index.constant()).Value());
1545 ASSERT(element_address.base() != TMP); // Allowed for load only. 1580 ASSERT(element_address.base() != TMP); // Allowed for load only.
1546 } else { 1581 } else {
1547 if (index.IsRegister()) { 1582 if (index.IsRegister()) {
1548 __ LoadElementAddressForRegIndex(address, 1583 __ LoadElementAddressForRegIndex(address,
1549 false, // Store. 1584 false, // Store.
1550 IsExternal(), class_id(), index_scale(), 1585 IsExternal(), class_id(), index_scale(),
1551 array, index.reg()); 1586 array, index.reg());
1552 } else { 1587 } else {
1553 __ LoadElementAddressForIntIndex(address, 1588 __ LoadElementAddressForIntIndex(address, IsExternal(), class_id(),
1554 IsExternal(), class_id(), index_scale(), 1589 index_scale(), array,
1555 array,
1556 Smi::Cast(index.constant()).Value()); 1590 Smi::Cast(index.constant()).Value());
1557 } 1591 }
1558 } 1592 }
1559 1593
1560 switch (class_id()) { 1594 switch (class_id()) {
1561 case kArrayCid: 1595 case kArrayCid:
1562 ASSERT(aligned()); 1596 ASSERT(aligned());
1563 if (ShouldEmitStoreBarrier()) { 1597 if (ShouldEmitStoreBarrier()) {
1564 Register value = locs()->in(2).reg(); 1598 Register value = locs()->in(2).reg();
1565 __ StoreIntoObject(array, element_address, value); 1599 __ StoreIntoObject(array, element_address, value);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 break; 1669 break;
1636 } 1670 }
1637 case kTypedDataFloat32ArrayCid: { 1671 case kTypedDataFloat32ArrayCid: {
1638 ASSERT(aligned()); 1672 ASSERT(aligned());
1639 FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg()); 1673 FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg());
1640 __ swc1(value, element_address); 1674 __ swc1(value, element_address);
1641 break; 1675 break;
1642 } 1676 }
1643 case kTypedDataFloat64ArrayCid: 1677 case kTypedDataFloat64ArrayCid:
1644 ASSERT(aligned()); 1678 ASSERT(aligned());
1645 __ StoreDToOffset(locs()->in(2).fpu_reg(), 1679 __ StoreDToOffset(locs()->in(2).fpu_reg(), element_address.base(),
1646 element_address.base(), element_address.offset()); 1680 element_address.offset());
1647 break; 1681 break;
1648 case kTypedDataInt32x4ArrayCid: 1682 case kTypedDataInt32x4ArrayCid:
1649 case kTypedDataFloat32x4ArrayCid: 1683 case kTypedDataFloat32x4ArrayCid:
1650 UNIMPLEMENTED(); 1684 UNIMPLEMENTED();
1651 break; 1685 break;
1652 default: 1686 default:
1653 UNREACHABLE(); 1687 UNREACHABLE();
1654 } 1688 }
1655 } 1689 }
1656 1690
1657 1691
1658 LocationSummary* GuardFieldClassInstr::MakeLocationSummary(Zone* zone, 1692 LocationSummary* GuardFieldClassInstr::MakeLocationSummary(Zone* zone,
1659 bool opt) const { 1693 bool opt) const {
1660 const intptr_t kNumInputs = 1; 1694 const intptr_t kNumInputs = 1;
1661 1695
1662 const intptr_t value_cid = value()->Type()->ToCid(); 1696 const intptr_t value_cid = value()->Type()->ToCid();
1663 const intptr_t field_cid = field().guarded_cid(); 1697 const intptr_t field_cid = field().guarded_cid();
1664 1698
1665 const bool emit_full_guard = !opt || (field_cid == kIllegalCid); 1699 const bool emit_full_guard = !opt || (field_cid == kIllegalCid);
1666 const bool needs_value_cid_temp_reg = 1700 const bool needs_value_cid_temp_reg =
1667 (value_cid == kDynamicCid) && (emit_full_guard || (field_cid != kSmiCid)); 1701 (value_cid == kDynamicCid) && (emit_full_guard || (field_cid != kSmiCid));
1668 const bool needs_field_temp_reg = emit_full_guard; 1702 const bool needs_field_temp_reg = emit_full_guard;
1669 1703
1670 intptr_t num_temps = 0; 1704 intptr_t num_temps = 0;
1671 if (needs_value_cid_temp_reg) { 1705 if (needs_value_cid_temp_reg) {
1672 num_temps++; 1706 num_temps++;
1673 } 1707 }
1674 if (needs_field_temp_reg) { 1708 if (needs_field_temp_reg) {
1675 num_temps++; 1709 num_temps++;
1676 } 1710 }
1677 1711
1678 LocationSummary* summary = new(zone) LocationSummary( 1712 LocationSummary* summary = new (zone)
1679 zone, kNumInputs, num_temps, LocationSummary::kNoCall); 1713 LocationSummary(zone, kNumInputs, num_temps, LocationSummary::kNoCall);
1680 summary->set_in(0, Location::RequiresRegister()); 1714 summary->set_in(0, Location::RequiresRegister());
1681 1715
1682 for (intptr_t i = 0; i < num_temps; i++) { 1716 for (intptr_t i = 0; i < num_temps; i++) {
1683 summary->set_temp(i, Location::RequiresRegister()); 1717 summary->set_temp(i, Location::RequiresRegister());
1684 } 1718 }
1685 1719
1686 return summary; 1720 return summary;
1687 } 1721 }
1688 1722
1689 1723
1690 void GuardFieldClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1724 void GuardFieldClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1691 ASSERT(sizeof(classid_t) == kInt16Size); 1725 ASSERT(sizeof(classid_t) == kInt16Size);
1692 __ Comment("GuardFieldClassInstr"); 1726 __ Comment("GuardFieldClassInstr");
1693 1727
1694 const intptr_t value_cid = value()->Type()->ToCid(); 1728 const intptr_t value_cid = value()->Type()->ToCid();
1695 const intptr_t field_cid = field().guarded_cid(); 1729 const intptr_t field_cid = field().guarded_cid();
1696 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid; 1730 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
1697 1731
1698 if (field_cid == kDynamicCid) { 1732 if (field_cid == kDynamicCid) {
1699 if (Compiler::IsBackgroundCompilation()) { 1733 if (Compiler::IsBackgroundCompilation()) {
1700 // Field state changed while compiling. 1734 // Field state changed while compiling.
1701 Compiler::AbortBackgroundCompilation(deopt_id(), 1735 Compiler::AbortBackgroundCompilation(
1736 deopt_id(),
1702 "GuardFieldClassInstr: field state changed while compiling"); 1737 "GuardFieldClassInstr: field state changed while compiling");
1703 } 1738 }
1704 ASSERT(!compiler->is_optimizing()); 1739 ASSERT(!compiler->is_optimizing());
1705 return; // Nothing to emit. 1740 return; // Nothing to emit.
1706 } 1741 }
1707 1742
1708 const bool emit_full_guard = 1743 const bool emit_full_guard =
1709 !compiler->is_optimizing() || (field_cid == kIllegalCid); 1744 !compiler->is_optimizing() || (field_cid == kIllegalCid);
1710 1745
1711 const bool needs_value_cid_temp_reg = 1746 const bool needs_value_cid_temp_reg =
1712 (value_cid == kDynamicCid) && (emit_full_guard || (field_cid != kSmiCid)); 1747 (value_cid == kDynamicCid) && (emit_full_guard || (field_cid != kSmiCid));
1713 1748
1714 const bool needs_field_temp_reg = emit_full_guard; 1749 const bool needs_field_temp_reg = emit_full_guard;
1715 1750
1716 const Register value_reg = locs()->in(0).reg(); 1751 const Register value_reg = locs()->in(0).reg();
1717 1752
1718 const Register value_cid_reg = needs_value_cid_temp_reg ? 1753 const Register value_cid_reg =
1719 locs()->temp(0).reg() : kNoRegister; 1754 needs_value_cid_temp_reg ? locs()->temp(0).reg() : kNoRegister;
1720 1755
1721 const Register field_reg = needs_field_temp_reg ? 1756 const Register field_reg = needs_field_temp_reg
1722 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; 1757 ? locs()->temp(locs()->temp_count() - 1).reg()
1758 : kNoRegister;
1723 1759
1724 Label ok, fail_label; 1760 Label ok, fail_label;
1725 1761
1726 Label* deopt = compiler->is_optimizing() ? 1762 Label* deopt =
1727 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; 1763 compiler->is_optimizing()
1764 ? compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField)
1765 : NULL;
1728 1766
1729 Label* fail = (deopt != NULL) ? deopt : &fail_label; 1767 Label* fail = (deopt != NULL) ? deopt : &fail_label;
1730 1768
1731 if (emit_full_guard) { 1769 if (emit_full_guard) {
1732 __ LoadObject(field_reg, Field::ZoneHandle(field().Original())); 1770 __ LoadObject(field_reg, Field::ZoneHandle(field().Original()));
1733 1771
1734 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); 1772 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
1735 FieldAddress field_nullability_operand( 1773 FieldAddress field_nullability_operand(field_reg,
1736 field_reg, Field::is_nullable_offset()); 1774 Field::is_nullable_offset());
1737 1775
1738 if (value_cid == kDynamicCid) { 1776 if (value_cid == kDynamicCid) {
1739 LoadValueCid(compiler, value_cid_reg, value_reg); 1777 LoadValueCid(compiler, value_cid_reg, value_reg);
1740 1778
1741 __ lhu(CMPRES1, field_cid_operand); 1779 __ lhu(CMPRES1, field_cid_operand);
1742 __ beq(value_cid_reg, CMPRES1, &ok); 1780 __ beq(value_cid_reg, CMPRES1, &ok);
1743 __ lhu(TMP, field_nullability_operand); 1781 __ lhu(TMP, field_nullability_operand);
1744 __ subu(CMPRES1, value_cid_reg, TMP); 1782 __ subu(CMPRES1, value_cid_reg, TMP);
1745 } else if (value_cid == kNullCid) { 1783 } else if (value_cid == kNullCid) {
1746 __ lhu(TMP, field_nullability_operand); 1784 __ lhu(TMP, field_nullability_operand);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 __ Bind(&ok); 1868 __ Bind(&ok);
1831 } 1869 }
1832 1870
1833 1871
1834 LocationSummary* GuardFieldLengthInstr::MakeLocationSummary(Zone* zone, 1872 LocationSummary* GuardFieldLengthInstr::MakeLocationSummary(Zone* zone,
1835 bool opt) const { 1873 bool opt) const {
1836 const intptr_t kNumInputs = 1; 1874 const intptr_t kNumInputs = 1;
1837 1875
1838 if (!opt || (field().guarded_list_length() == Field::kUnknownFixedLength)) { 1876 if (!opt || (field().guarded_list_length() == Field::kUnknownFixedLength)) {
1839 const intptr_t kNumTemps = 1; 1877 const intptr_t kNumTemps = 1;
1840 LocationSummary* summary = new(zone) LocationSummary( 1878 LocationSummary* summary = new (zone)
1841 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1879 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1842 summary->set_in(0, Location::RequiresRegister()); 1880 summary->set_in(0, Location::RequiresRegister());
1843 // We need temporaries for field object. 1881 // We need temporaries for field object.
1844 summary->set_temp(0, Location::RequiresRegister()); 1882 summary->set_temp(0, Location::RequiresRegister());
1845 return summary; 1883 return summary;
1846 } 1884 }
1847 LocationSummary* summary = new(zone) LocationSummary( 1885 LocationSummary* summary =
1848 zone, kNumInputs, 0, LocationSummary::kNoCall); 1886 new (zone) LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall);
1849 summary->set_in(0, Location::RequiresRegister()); 1887 summary->set_in(0, Location::RequiresRegister());
1850 return summary; 1888 return summary;
1851 } 1889 }
1852 1890
1853 1891
1854 void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1892 void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1855 if (field().guarded_list_length() == Field::kNoFixedLength) { 1893 if (field().guarded_list_length() == Field::kNoFixedLength) {
1856 if (Compiler::IsBackgroundCompilation()) { 1894 if (Compiler::IsBackgroundCompilation()) {
1857 // Field state changed while compiling. 1895 // Field state changed while compiling.
1858 Compiler::AbortBackgroundCompilation(deopt_id(), 1896 Compiler::AbortBackgroundCompilation(
1897 deopt_id(),
1859 "GuardFieldLengthInstr: field state changed while compiling"); 1898 "GuardFieldLengthInstr: field state changed while compiling");
1860 } 1899 }
1861 ASSERT(!compiler->is_optimizing()); 1900 ASSERT(!compiler->is_optimizing());
1862 return; // Nothing to emit. 1901 return; // Nothing to emit.
1863 } 1902 }
1864 1903
1865 Label* deopt = compiler->is_optimizing() ? 1904 Label* deopt =
1866 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; 1905 compiler->is_optimizing()
1906 ? compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField)
1907 : NULL;
1867 1908
1868 const Register value_reg = locs()->in(0).reg(); 1909 const Register value_reg = locs()->in(0).reg();
1869 1910
1870 if (!compiler->is_optimizing() || 1911 if (!compiler->is_optimizing() ||
1871 (field().guarded_list_length() == Field::kUnknownFixedLength)) { 1912 (field().guarded_list_length() == Field::kUnknownFixedLength)) {
1872 const Register field_reg = locs()->temp(0).reg(); 1913 const Register field_reg = locs()->temp(0).reg();
1873 1914
1874 Label ok; 1915 Label ok;
1875 1916
1876 __ LoadObject(field_reg, Field::ZoneHandle(field().Original())); 1917 __ LoadObject(field_reg, Field::ZoneHandle(field().Original()));
1877 1918
1878 __ lb(CMPRES1, FieldAddress(field_reg, 1919 __ lb(CMPRES1,
1879 Field::guarded_list_length_in_object_offset_offset())); 1920 FieldAddress(field_reg,
1921 Field::guarded_list_length_in_object_offset_offset()));
1880 __ blez(CMPRES1, &ok); 1922 __ blez(CMPRES1, &ok);
1881 1923
1882 __ lw(CMPRES2, FieldAddress(field_reg, 1924 __ lw(CMPRES2,
1883 Field::guarded_list_length_offset())); 1925 FieldAddress(field_reg, Field::guarded_list_length_offset()));
1884 1926
1885 // Load the length from the value. GuardFieldClass already verified that 1927 // Load the length from the value. GuardFieldClass already verified that
1886 // value's class matches guarded class id of the field. 1928 // value's class matches guarded class id of the field.
1887 // CMPRES1 contains offset already corrected by -kHeapObjectTag that is 1929 // CMPRES1 contains offset already corrected by -kHeapObjectTag that is
1888 // why we can use Address instead of FieldAddress. 1930 // why we can use Address instead of FieldAddress.
1889 __ addu(TMP, value_reg, CMPRES1); 1931 __ addu(TMP, value_reg, CMPRES1);
1890 __ lw(TMP, Address(TMP)); 1932 __ lw(TMP, Address(TMP));
1891 1933
1892 if (deopt == NULL) { 1934 if (deopt == NULL) {
1893 __ beq(CMPRES2, TMP, &ok); 1935 __ beq(CMPRES2, TMP, &ok);
1894 1936
1895 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1937 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1896 __ sw(field_reg, Address(SP, 1 * kWordSize)); 1938 __ sw(field_reg, Address(SP, 1 * kWordSize));
1897 __ sw(value_reg, Address(SP, 0 * kWordSize)); 1939 __ sw(value_reg, Address(SP, 0 * kWordSize));
1898 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); 1940 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2);
1899 __ Drop(2); // Drop the field and the value. 1941 __ Drop(2); // Drop the field and the value.
1900 } else { 1942 } else {
1901 __ bne(CMPRES2, TMP, deopt); 1943 __ bne(CMPRES2, TMP, deopt);
1902 } 1944 }
1903 1945
1904 __ Bind(&ok); 1946 __ Bind(&ok);
1905 } else { 1947 } else {
1906 ASSERT(compiler->is_optimizing()); 1948 ASSERT(compiler->is_optimizing());
1907 ASSERT(field().guarded_list_length() >= 0); 1949 ASSERT(field().guarded_list_length() >= 0);
1908 ASSERT(field().guarded_list_length_in_object_offset() != 1950 ASSERT(field().guarded_list_length_in_object_offset() !=
1909 Field::kUnknownLengthOffset); 1951 Field::kUnknownLengthOffset);
1910 1952
1911 __ lw(CMPRES1, 1953 __ lw(CMPRES1,
1912 FieldAddress(value_reg, 1954 FieldAddress(value_reg,
1913 field().guarded_list_length_in_object_offset())); 1955 field().guarded_list_length_in_object_offset()));
1914 __ LoadImmediate(TMP, Smi::RawValue(field().guarded_list_length())); 1956 __ LoadImmediate(TMP, Smi::RawValue(field().guarded_list_length()));
1915 __ bne(CMPRES1, TMP, deopt); 1957 __ bne(CMPRES1, TMP, deopt);
1916 } 1958 }
1917 } 1959 }
1918 1960
1919 1961
1920 class BoxAllocationSlowPath : public SlowPathCode { 1962 class BoxAllocationSlowPath : public SlowPathCode {
1921 public: 1963 public:
1922 BoxAllocationSlowPath(Instruction* instruction, 1964 BoxAllocationSlowPath(Instruction* instruction,
1923 const Class& cls, 1965 const Class& cls,
1924 Register result) 1966 Register result)
1925 : instruction_(instruction), 1967 : instruction_(instruction), cls_(cls), result_(result) {}
1926 cls_(cls),
1927 result_(result) { }
1928 1968
1929 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1969 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1930 if (Assembler::EmittingComments()) { 1970 if (Assembler::EmittingComments()) {
1931 __ Comment("%s slow path allocation of %s", 1971 __ Comment("%s slow path allocation of %s", instruction_->DebugName(),
1932 instruction_->DebugName(),
1933 String::Handle(cls_.ScrubbedName()).ToCString()); 1972 String::Handle(cls_.ScrubbedName()).ToCString());
1934 } 1973 }
1935 __ Bind(entry_label()); 1974 __ Bind(entry_label());
1936 const Code& stub = Code::ZoneHandle( 1975 const Code& stub = Code::ZoneHandle(
1937 compiler->zone(), StubCode::GetAllocationStubForClass(cls_)); 1976 compiler->zone(), StubCode::GetAllocationStubForClass(cls_));
1938 const StubEntry stub_entry(stub); 1977 const StubEntry stub_entry(stub);
1939 1978
1940 LocationSummary* locs = instruction_->locs(); 1979 LocationSummary* locs = instruction_->locs();
1941 locs->live_registers()->Remove(Location::RegisterLocation(result_)); 1980 locs->live_registers()->Remove(Location::RegisterLocation(result_));
1942 1981
1943 compiler->SaveLiveRegisters(locs); 1982 compiler->SaveLiveRegisters(locs);
1944 compiler->GenerateCall(TokenPosition::kNoSource, // No token position. 1983 compiler->GenerateCall(TokenPosition::kNoSource, // No token position.
1945 stub_entry, 1984 stub_entry, RawPcDescriptors::kOther, locs);
1946 RawPcDescriptors::kOther,
1947 locs);
1948 compiler->AddStubCallTarget(stub); 1985 compiler->AddStubCallTarget(stub);
1949 if (result_ != V0) { 1986 if (result_ != V0) {
1950 __ mov(result_, V0); 1987 __ mov(result_, V0);
1951 } 1988 }
1952 compiler->RestoreLiveRegisters(locs); 1989 compiler->RestoreLiveRegisters(locs);
1953 __ b(exit_label()); 1990 __ b(exit_label());
1954 } 1991 }
1955 1992
1956 static void Allocate(FlowGraphCompiler* compiler, 1993 static void Allocate(FlowGraphCompiler* compiler,
1957 Instruction* instruction, 1994 Instruction* instruction,
1958 const Class& cls, 1995 const Class& cls,
1959 Register result, 1996 Register result,
1960 Register temp) { 1997 Register temp) {
1961 if (compiler->intrinsic_mode()) { 1998 if (compiler->intrinsic_mode()) {
1962 __ TryAllocate(cls, 1999 __ TryAllocate(cls, compiler->intrinsic_slow_path_label(), result, temp);
1963 compiler->intrinsic_slow_path_label(),
1964 result,
1965 temp);
1966 } else { 2000 } else {
1967 BoxAllocationSlowPath* slow_path = 2001 BoxAllocationSlowPath* slow_path =
1968 new BoxAllocationSlowPath(instruction, cls, result); 2002 new BoxAllocationSlowPath(instruction, cls, result);
1969 compiler->AddSlowPathCode(slow_path); 2003 compiler->AddSlowPathCode(slow_path);
1970 2004
1971 __ TryAllocate(cls, 2005 __ TryAllocate(cls, slow_path->entry_label(), result, temp);
1972 slow_path->entry_label(),
1973 result,
1974 temp);
1975 __ Bind(slow_path->exit_label()); 2006 __ Bind(slow_path->exit_label());
1976 } 2007 }
1977 } 2008 }
1978 2009
1979 private: 2010 private:
1980 Instruction* instruction_; 2011 Instruction* instruction_;
1981 const Class& cls_; 2012 const Class& cls_;
1982 const Register result_; 2013 const Register result_;
1983 }; 2014 };
1984 2015
1985 2016
1986 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone, 2017 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone,
1987 bool opt) const { 2018 bool opt) const {
1988 const intptr_t kNumInputs = 2; 2019 const intptr_t kNumInputs = 2;
1989 const intptr_t kNumTemps = 2020 const intptr_t kNumTemps =
1990 (IsUnboxedStore() && opt) ? 2 : 2021 (IsUnboxedStore() && opt) ? 2 : ((IsPotentialUnboxedStore()) ? 3 : 0);
1991 ((IsPotentialUnboxedStore()) ? 3 : 0); 2022 LocationSummary* summary = new (zone)
1992 LocationSummary* summary = new(zone) LocationSummary( 2023 LocationSummary(zone, kNumInputs, kNumTemps,
1993 zone, kNumInputs, kNumTemps, 2024 ((IsUnboxedStore() && opt && is_initialization()) ||
1994 ((IsUnboxedStore() && opt && is_initialization()) || 2025 IsPotentialUnboxedStore())
1995 IsPotentialUnboxedStore()) 2026 ? LocationSummary::kCallOnSlowPath
1996 ? LocationSummary::kCallOnSlowPath 2027 : LocationSummary::kNoCall);
1997 : LocationSummary::kNoCall);
1998 2028
1999 summary->set_in(0, Location::RequiresRegister()); 2029 summary->set_in(0, Location::RequiresRegister());
2000 if (IsUnboxedStore() && opt) { 2030 if (IsUnboxedStore() && opt) {
2001 summary->set_in(1, Location::RequiresFpuRegister()); 2031 summary->set_in(1, Location::RequiresFpuRegister());
2002 summary->set_temp(0, Location::RequiresRegister()); 2032 summary->set_temp(0, Location::RequiresRegister());
2003 summary->set_temp(1, Location::RequiresRegister()); 2033 summary->set_temp(1, Location::RequiresRegister());
2004 } else if (IsPotentialUnboxedStore()) { 2034 } else if (IsPotentialUnboxedStore()) {
2005 summary->set_in(1, ShouldEmitStoreBarrier() 2035 summary->set_in(1, ShouldEmitStoreBarrier() ? Location::WritableRegister()
2006 ? Location::WritableRegister() 2036 : Location::RequiresRegister());
2007 : Location::RequiresRegister());
2008 summary->set_temp(0, Location::RequiresRegister()); 2037 summary->set_temp(0, Location::RequiresRegister());
2009 summary->set_temp(1, Location::RequiresRegister()); 2038 summary->set_temp(1, Location::RequiresRegister());
2010 summary->set_temp(2, opt ? Location::RequiresFpuRegister() 2039 summary->set_temp(2, opt ? Location::RequiresFpuRegister()
2011 : Location::FpuRegisterLocation(D1)); 2040 : Location::FpuRegisterLocation(D1));
2012 } else { 2041 } else {
2013 summary->set_in(1, ShouldEmitStoreBarrier() 2042 summary->set_in(1, ShouldEmitStoreBarrier()
2014 ? Location::WritableRegister() 2043 ? Location::WritableRegister()
2015 : Location::RegisterOrConstant(value())); 2044 : Location::RegisterOrConstant(value()));
2016 } 2045 }
2017 return summary; 2046 return summary;
2018 } 2047 }
2019 2048
2020 2049
2021 static void EnsureMutableBox(FlowGraphCompiler* compiler, 2050 static void EnsureMutableBox(FlowGraphCompiler* compiler,
2022 StoreInstanceFieldInstr* instruction, 2051 StoreInstanceFieldInstr* instruction,
2023 Register box_reg, 2052 Register box_reg,
2024 const Class& cls, 2053 const Class& cls,
2025 Register instance_reg, 2054 Register instance_reg,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 2088
2060 BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2); 2089 BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
2061 __ mov(temp2, temp); 2090 __ mov(temp2, temp);
2062 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); 2091 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
2063 } else { 2092 } else {
2064 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); 2093 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_));
2065 } 2094 }
2066 switch (cid) { 2095 switch (cid) {
2067 case kDoubleCid: 2096 case kDoubleCid:
2068 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 2097 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2069 break; 2098 break;
2070 default: 2099 default:
2071 UNREACHABLE(); 2100 UNREACHABLE();
2072 } 2101 }
2073 return; 2102 return;
2074 } 2103 }
2075 2104
2076 if (IsPotentialUnboxedStore()) { 2105 if (IsPotentialUnboxedStore()) {
2077 Register value_reg = locs()->in(1).reg(); 2106 Register value_reg = locs()->in(1).reg();
2078 Register temp = locs()->temp(0).reg(); 2107 Register temp = locs()->temp(0).reg();
2079 Register temp2 = locs()->temp(1).reg(); 2108 Register temp2 = locs()->temp(1).reg();
(...skipping 23 matching lines...) Expand all
2103 // Fall through. 2132 // Fall through.
2104 __ b(&store_pointer); 2133 __ b(&store_pointer);
2105 2134
2106 if (!compiler->is_optimizing()) { 2135 if (!compiler->is_optimizing()) {
2107 locs()->live_registers()->Add(locs()->in(0)); 2136 locs()->live_registers()->Add(locs()->in(0));
2108 locs()->live_registers()->Add(locs()->in(1)); 2137 locs()->live_registers()->Add(locs()->in(1));
2109 } 2138 }
2110 2139
2111 { 2140 {
2112 __ Bind(&store_double); 2141 __ Bind(&store_double);
2113 EnsureMutableBox(compiler, 2142 EnsureMutableBox(compiler, this, temp, compiler->double_class(),
2114 this, 2143 instance_reg, offset_in_bytes_, temp2);
2115 temp, 2144 __ LoadDFromOffset(fpu_temp, value_reg,
2116 compiler->double_class(),
2117 instance_reg,
2118 offset_in_bytes_,
2119 temp2);
2120 __ LoadDFromOffset(fpu_temp,
2121 value_reg,
2122 Double::value_offset() - kHeapObjectTag); 2145 Double::value_offset() - kHeapObjectTag);
2123 __ StoreDToOffset(fpu_temp, temp, 2146 __ StoreDToOffset(fpu_temp, temp,
2124 Double::value_offset() - kHeapObjectTag); 2147 Double::value_offset() - kHeapObjectTag);
2125 __ b(&skip_store); 2148 __ b(&skip_store);
2126 } 2149 }
2127 2150
2128 __ Bind(&store_pointer); 2151 __ Bind(&store_pointer);
2129 } 2152 }
2130 2153
2131 if (ShouldEmitStoreBarrier()) { 2154 if (ShouldEmitStoreBarrier()) {
2132 Register value_reg = locs()->in(1).reg(); 2155 Register value_reg = locs()->in(1).reg();
2133 __ StoreIntoObjectOffset(instance_reg, 2156 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, value_reg,
2134 offset_in_bytes_,
2135 value_reg,
2136 CanValueBeSmi()); 2157 CanValueBeSmi());
2137 } else { 2158 } else {
2138 if (locs()->in(1).IsConstant()) { 2159 if (locs()->in(1).IsConstant()) {
2139 __ StoreIntoObjectNoBarrierOffset( 2160 __ StoreIntoObjectNoBarrierOffset(instance_reg, offset_in_bytes_,
2140 instance_reg, 2161 locs()->in(1).constant());
2141 offset_in_bytes_,
2142 locs()->in(1).constant());
2143 } else { 2162 } else {
2144 Register value_reg = locs()->in(1).reg(); 2163 Register value_reg = locs()->in(1).reg();
2145 __ StoreIntoObjectNoBarrierOffset(instance_reg, 2164 __ StoreIntoObjectNoBarrierOffset(instance_reg, offset_in_bytes_,
2146 offset_in_bytes_,
2147 value_reg); 2165 value_reg);
2148 } 2166 }
2149 } 2167 }
2150 __ Bind(&skip_store); 2168 __ Bind(&skip_store);
2151 } 2169 }
2152 2170
2153 2171
2154 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(Zone* zone, 2172 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(Zone* zone,
2155 bool opt) const { 2173 bool opt) const {
2156 const intptr_t kNumInputs = 1; 2174 const intptr_t kNumInputs = 1;
2157 const intptr_t kNumTemps = 0; 2175 const intptr_t kNumTemps = 0;
2158 LocationSummary* summary = new(zone) LocationSummary( 2176 LocationSummary* summary = new (zone)
2159 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 2177 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
2160 summary->set_in(0, Location::RequiresRegister()); 2178 summary->set_in(0, Location::RequiresRegister());
2161 summary->set_out(0, Location::RequiresRegister()); 2179 summary->set_out(0, Location::RequiresRegister());
2162 return summary; 2180 return summary;
2163 } 2181 }
2164 2182
2165 2183
2166 // When the parser is building an implicit static getter for optimization, 2184 // When the parser is building an implicit static getter for optimization,
2167 // it can generate a function body where deoptimization ids do not line up 2185 // it can generate a function body where deoptimization ids do not line up
2168 // with the unoptimized code. 2186 // with the unoptimized code.
2169 // 2187 //
2170 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 2188 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
2171 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2189 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2172 __ Comment("LoadStaticFieldInstr"); 2190 __ Comment("LoadStaticFieldInstr");
2173 Register field = locs()->in(0).reg(); 2191 Register field = locs()->in(0).reg();
2174 Register result = locs()->out(0).reg(); 2192 Register result = locs()->out(0).reg();
2175 __ LoadFromOffset(result, 2193 __ LoadFromOffset(result, field,
2176 field,
2177 Field::static_value_offset() - kHeapObjectTag); 2194 Field::static_value_offset() - kHeapObjectTag);
2178 } 2195 }
2179 2196
2180 2197
2181 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone, 2198 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
2182 bool opt) const { 2199 bool opt) const {
2183 LocationSummary* locs = new(zone) LocationSummary( 2200 LocationSummary* locs =
2184 zone, 1, 1, LocationSummary::kNoCall); 2201 new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
2185 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 2202 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
2186 : Location::RequiresRegister()); 2203 : Location::RequiresRegister());
2187 locs->set_temp(0, Location::RequiresRegister()); 2204 locs->set_temp(0, Location::RequiresRegister());
2188 return locs; 2205 return locs;
2189 } 2206 }
2190 2207
2191 2208
2192 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2209 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2193 __ Comment("StoreStaticFieldInstr"); 2210 __ Comment("StoreStaticFieldInstr");
2194 Register value = locs()->in(0).reg(); 2211 Register value = locs()->in(0).reg();
2195 Register temp = locs()->temp(0).reg(); 2212 Register temp = locs()->temp(0).reg();
2196 2213
2197 __ LoadObject(temp, Field::ZoneHandle(Z, field().Original())); 2214 __ LoadObject(temp, Field::ZoneHandle(Z, field().Original()));
2198 if (this->value()->NeedsStoreBuffer()) { 2215 if (this->value()->NeedsStoreBuffer()) {
2199 __ StoreIntoObject(temp, 2216 __ StoreIntoObject(temp, FieldAddress(temp, Field::static_value_offset()),
2200 FieldAddress(temp, Field::static_value_offset()), 2217 value, CanValueBeSmi());
2201 value,
2202 CanValueBeSmi());
2203 } else { 2218 } else {
2204 __ StoreIntoObjectNoBarrier( 2219 __ StoreIntoObjectNoBarrier(
2205 temp, FieldAddress(temp, Field::static_value_offset()), value); 2220 temp, FieldAddress(temp, Field::static_value_offset()), value);
2206 } 2221 }
2207 } 2222 }
2208 2223
2209 2224
2210 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, 2225 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
2211 bool opt) const { 2226 bool opt) const {
2212 const intptr_t kNumInputs = 2; 2227 const intptr_t kNumInputs = 2;
2213 const intptr_t kNumTemps = 0; 2228 const intptr_t kNumTemps = 0;
2214 LocationSummary* summary = new(zone) LocationSummary( 2229 LocationSummary* summary = new (zone)
2215 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2230 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2216 summary->set_in(0, Location::RegisterLocation(A0)); 2231 summary->set_in(0, Location::RegisterLocation(A0));
2217 summary->set_in(1, Location::RegisterLocation(A1)); 2232 summary->set_in(1, Location::RegisterLocation(A1));
2218 summary->set_out(0, Location::RegisterLocation(V0)); 2233 summary->set_out(0, Location::RegisterLocation(V0));
2219 return summary; 2234 return summary;
2220 } 2235 }
2221 2236
2222 2237
2223 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2238 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2224 ASSERT(locs()->in(0).reg() == A0); // Value. 2239 ASSERT(locs()->in(0).reg() == A0); // Value.
2225 ASSERT(locs()->in(1).reg() == A1); // Instantiator type arguments. 2240 ASSERT(locs()->in(1).reg() == A1); // Instantiator type arguments.
2226 2241
2227 __ Comment("InstanceOfInstr"); 2242 __ Comment("InstanceOfInstr");
2228 compiler->GenerateInstanceOf(token_pos(), 2243 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), negate_result(),
2229 deopt_id(),
2230 type(),
2231 negate_result(),
2232 locs()); 2244 locs());
2233 ASSERT(locs()->out(0).reg() == V0); 2245 ASSERT(locs()->out(0).reg() == V0);
2234 } 2246 }
2235 2247
2236 2248
2237 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, 2249 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone,
2238 bool opt) const { 2250 bool opt) const {
2239 const intptr_t kNumInputs = 2; 2251 const intptr_t kNumInputs = 2;
2240 const intptr_t kNumTemps = 0; 2252 const intptr_t kNumTemps = 0;
2241 LocationSummary* locs = new(zone) LocationSummary( 2253 LocationSummary* locs = new (zone)
2242 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2254 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2243 locs->set_in(0, Location::RegisterLocation(A0)); 2255 locs->set_in(0, Location::RegisterLocation(A0));
2244 locs->set_in(1, Location::RegisterLocation(A1)); 2256 locs->set_in(1, Location::RegisterLocation(A1));
2245 locs->set_out(0, Location::RegisterLocation(V0)); 2257 locs->set_out(0, Location::RegisterLocation(V0));
2246 return locs; 2258 return locs;
2247 } 2259 }
2248 2260
2249 2261
2250 // Inlines array allocation for known constant values. 2262 // Inlines array allocation for known constant values.
2251 static void InlineArrayAllocation(FlowGraphCompiler* compiler, 2263 static void InlineArrayAllocation(FlowGraphCompiler* compiler,
2252 intptr_t num_elements, 2264 intptr_t num_elements,
2253 Label* slow_path, 2265 Label* slow_path,
2254 Label* done) { 2266 Label* done) {
2255 const int kInlineArraySize = 12; // Same as kInlineInstanceSize. 2267 const int kInlineArraySize = 12; // Same as kInlineInstanceSize.
2256 const Register kLengthReg = A1; 2268 const Register kLengthReg = A1;
2257 const Register kElemTypeReg = A0; 2269 const Register kElemTypeReg = A0;
2258 const intptr_t instance_size = Array::InstanceSize(num_elements); 2270 const intptr_t instance_size = Array::InstanceSize(num_elements);
2259 2271
2260 __ TryAllocateArray(kArrayCid, instance_size, slow_path, 2272 __ TryAllocateArray(kArrayCid, instance_size, slow_path,
2261 V0, // instance 2273 V0, // instance
2262 T1, // end address 2274 T1, // end address
2263 T2, 2275 T2, T3);
2264 T3);
2265 // V0: new object start as a tagged pointer. 2276 // V0: new object start as a tagged pointer.
2266 // T1: new object end address. 2277 // T1: new object end address.
2267 2278
2268 // Store the type argument field. 2279 // Store the type argument field.
2269 __ StoreIntoObjectNoBarrier(V0, 2280 __ StoreIntoObjectNoBarrier(
2270 FieldAddress(V0, Array::type_arguments_offset()), 2281 V0, FieldAddress(V0, Array::type_arguments_offset()), kElemTypeReg);
2271 kElemTypeReg);
2272 2282
2273 // Set the length field. 2283 // Set the length field.
2274 __ StoreIntoObjectNoBarrier(V0, 2284 __ StoreIntoObjectNoBarrier(V0, FieldAddress(V0, Array::length_offset()),
2275 FieldAddress(V0, Array::length_offset()),
2276 kLengthReg); 2285 kLengthReg);
2277 2286
2278 // Initialize all array elements to raw_null. 2287 // Initialize all array elements to raw_null.
2279 // V0: new object start as a tagged pointer. 2288 // V0: new object start as a tagged pointer.
2280 // T1: new object end address. 2289 // T1: new object end address.
2281 // T2: iterator which initially points to the start of the variable 2290 // T2: iterator which initially points to the start of the variable
2282 // data area to be initialized. 2291 // data area to be initialized.
2283 // T7: null. 2292 // T7: null.
2284 if (num_elements > 0) { 2293 if (num_elements > 0) {
2285 const intptr_t array_size = instance_size - sizeof(RawArray); 2294 const intptr_t array_size = instance_size - sizeof(RawArray);
(...skipping 19 matching lines...) Expand all
2305 2314
2306 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2315 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2307 __ Comment("CreateArrayInstr"); 2316 __ Comment("CreateArrayInstr");
2308 const Register kLengthReg = A1; 2317 const Register kLengthReg = A1;
2309 const Register kElemTypeReg = A0; 2318 const Register kElemTypeReg = A0;
2310 const Register kResultReg = V0; 2319 const Register kResultReg = V0;
2311 ASSERT(locs()->in(0).reg() == kElemTypeReg); 2320 ASSERT(locs()->in(0).reg() == kElemTypeReg);
2312 ASSERT(locs()->in(1).reg() == kLengthReg); 2321 ASSERT(locs()->in(1).reg() == kLengthReg);
2313 2322
2314 Label slow_path, done; 2323 Label slow_path, done;
2315 if (compiler->is_optimizing() && 2324 if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
2316 !FLAG_precompiled_mode &&
2317 num_elements()->BindsToConstant() && 2325 num_elements()->BindsToConstant() &&
2318 num_elements()->BoundConstant().IsSmi()) { 2326 num_elements()->BoundConstant().IsSmi()) {
2319 const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value(); 2327 const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
2320 if ((length >= 0) && (length <= Array::kMaxElements)) { 2328 if ((length >= 0) && (length <= Array::kMaxElements)) {
2321 Label slow_path, done; 2329 Label slow_path, done;
2322 InlineArrayAllocation(compiler, length, &slow_path, &done); 2330 InlineArrayAllocation(compiler, length, &slow_path, &done);
2323 __ Bind(&slow_path); 2331 __ Bind(&slow_path);
2324 __ PushObject(Object::null_object()); // Make room for the result. 2332 __ PushObject(Object::null_object()); // Make room for the result.
2325 __ Push(kLengthReg); // length. 2333 __ Push(kLengthReg); // length.
2326 __ Push(kElemTypeReg); 2334 __ Push(kElemTypeReg);
2327 compiler->GenerateRuntimeCall(token_pos(), 2335 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2328 deopt_id(), 2336 kAllocateArrayRuntimeEntry, 2, locs());
2329 kAllocateArrayRuntimeEntry,
2330 2,
2331 locs());
2332 __ Drop(2); 2337 __ Drop(2);
2333 __ Pop(kResultReg); 2338 __ Pop(kResultReg);
2334 __ Bind(&done); 2339 __ Bind(&done);
2335 return; 2340 return;
2336 } 2341 }
2337 } 2342 }
2338 2343
2339 __ Bind(&slow_path); 2344 __ Bind(&slow_path);
2340 const Code& stub = Code::ZoneHandle(compiler->zone(), 2345 const Code& stub = Code::ZoneHandle(compiler->zone(),
2341 StubCode::AllocateArray_entry()->code()); 2346 StubCode::AllocateArray_entry()->code());
2342 compiler->AddStubCallTarget(stub); 2347 compiler->AddStubCallTarget(stub);
2343 compiler->GenerateCall(token_pos(), 2348 compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(),
2344 *StubCode::AllocateArray_entry(), 2349 RawPcDescriptors::kOther, locs());
2345 RawPcDescriptors::kOther,
2346 locs());
2347 __ Bind(&done); 2350 __ Bind(&done);
2348 ASSERT(locs()->out(0).reg() == kResultReg); 2351 ASSERT(locs()->out(0).reg() == kResultReg);
2349 } 2352 }
2350 2353
2351 2354
2352 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone, 2355 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
2353 bool opt) const { 2356 bool opt) const {
2354 const intptr_t kNumInputs = 1; 2357 const intptr_t kNumInputs = 1;
2355 const intptr_t kNumTemps = 2358 const intptr_t kNumTemps =
2356 (IsUnboxedLoad() && opt) ? 1 : 2359 (IsUnboxedLoad() && opt) ? 1 : ((IsPotentialUnboxedLoad()) ? 2 : 0);
2357 ((IsPotentialUnboxedLoad()) ? 2 : 0); 2360 LocationSummary* locs = new (zone) LocationSummary(
2358 LocationSummary* locs = new(zone) LocationSummary( 2361 zone, kNumInputs, kNumTemps, (opt && !IsPotentialUnboxedLoad())
2359 zone, kNumInputs, kNumTemps, 2362 ? LocationSummary::kNoCall
2360 (opt && !IsPotentialUnboxedLoad()) 2363 : LocationSummary::kCallOnSlowPath);
2361 ? LocationSummary::kNoCall
2362 : LocationSummary::kCallOnSlowPath);
2363 2364
2364 locs->set_in(0, Location::RequiresRegister()); 2365 locs->set_in(0, Location::RequiresRegister());
2365 2366
2366 if (IsUnboxedLoad() && opt) { 2367 if (IsUnboxedLoad() && opt) {
2367 locs->set_temp(0, Location::RequiresRegister()); 2368 locs->set_temp(0, Location::RequiresRegister());
2368 } else if (IsPotentialUnboxedLoad()) { 2369 } else if (IsPotentialUnboxedLoad()) {
2369 locs->set_temp(0, opt ? Location::RequiresFpuRegister() 2370 locs->set_temp(0, opt ? Location::RequiresFpuRegister()
2370 : Location::FpuRegisterLocation(D1)); 2371 : Location::FpuRegisterLocation(D1));
2371 locs->set_temp(1, Location::RequiresRegister()); 2372 locs->set_temp(1, Location::RequiresRegister());
2372 } 2373 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 2419
2419 // Fall through. 2420 // Fall through.
2420 __ b(&load_pointer); 2421 __ b(&load_pointer);
2421 2422
2422 if (!compiler->is_optimizing()) { 2423 if (!compiler->is_optimizing()) {
2423 locs()->live_registers()->Add(locs()->in(0)); 2424 locs()->live_registers()->Add(locs()->in(0));
2424 } 2425 }
2425 2426
2426 { 2427 {
2427 __ Bind(&load_double); 2428 __ Bind(&load_double);
2428 BoxAllocationSlowPath::Allocate( 2429 BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
2429 compiler, this, compiler->double_class(), result_reg, temp); 2430 result_reg, temp);
2430 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); 2431 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2431 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); 2432 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2432 __ StoreDToOffset(value, 2433 __ StoreDToOffset(value, result_reg,
2433 result_reg,
2434 Double::value_offset() - kHeapObjectTag); 2434 Double::value_offset() - kHeapObjectTag);
2435 __ b(&done); 2435 __ b(&done);
2436 } 2436 }
2437 2437
2438 __ Bind(&load_pointer); 2438 __ Bind(&load_pointer);
2439 } 2439 }
2440 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); 2440 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes());
2441 __ Bind(&done); 2441 __ Bind(&done);
2442 } 2442 }
2443 2443
2444 2444
2445 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, 2445 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
2446 bool opt) const { 2446 bool opt) const {
2447 const intptr_t kNumInputs = 1; 2447 const intptr_t kNumInputs = 1;
2448 const intptr_t kNumTemps = 0; 2448 const intptr_t kNumTemps = 0;
2449 LocationSummary* locs = new(zone) LocationSummary( 2449 LocationSummary* locs = new (zone)
2450 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2450 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2451 locs->set_in(0, Location::RegisterLocation(T0)); 2451 locs->set_in(0, Location::RegisterLocation(T0));
2452 locs->set_out(0, Location::RegisterLocation(T0)); 2452 locs->set_out(0, Location::RegisterLocation(T0));
2453 return locs; 2453 return locs;
2454 } 2454 }
2455 2455
2456 2456
2457 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2457 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2458 __ Comment("InstantiateTypeInstr"); 2458 __ Comment("InstantiateTypeInstr");
2459 Register instantiator_reg = locs()->in(0).reg(); 2459 Register instantiator_reg = locs()->in(0).reg();
2460 Register result_reg = locs()->out(0).reg(); 2460 Register result_reg = locs()->out(0).reg();
2461 2461
2462 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2462 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2463 // A runtime call to instantiate the type is required. 2463 // A runtime call to instantiate the type is required.
2464 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 2464 __ addiu(SP, SP, Immediate(-3 * kWordSize));
2465 __ LoadObject(TMP, Object::null_object()); 2465 __ LoadObject(TMP, Object::null_object());
2466 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. 2466 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result.
2467 __ LoadObject(TMP, type()); 2467 __ LoadObject(TMP, type());
2468 __ sw(TMP, Address(SP, 1 * kWordSize)); 2468 __ sw(TMP, Address(SP, 1 * kWordSize));
2469 // Push instantiator type arguments. 2469 // Push instantiator type arguments.
2470 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); 2470 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
2471 2471
2472 compiler->GenerateRuntimeCall(token_pos(), 2472 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2473 deopt_id(), 2473 kInstantiateTypeRuntimeEntry, 2, locs());
2474 kInstantiateTypeRuntimeEntry,
2475 2,
2476 locs());
2477 // Pop instantiated type. 2474 // Pop instantiated type.
2478 __ lw(result_reg, Address(SP, 2 * kWordSize)); 2475 __ lw(result_reg, Address(SP, 2 * kWordSize));
2479 // Drop instantiator and uninstantiated type. 2476 // Drop instantiator and uninstantiated type.
2480 __ addiu(SP, SP, Immediate(3 * kWordSize)); 2477 __ addiu(SP, SP, Immediate(3 * kWordSize));
2481 ASSERT(instantiator_reg == result_reg); 2478 ASSERT(instantiator_reg == result_reg);
2482 } 2479 }
2483 2480
2484 2481
2485 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( 2482 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2486 Zone* zone, bool opt) const { 2483 Zone* zone,
2484 bool opt) const {
2487 const intptr_t kNumInputs = 1; 2485 const intptr_t kNumInputs = 1;
2488 const intptr_t kNumTemps = 0; 2486 const intptr_t kNumTemps = 0;
2489 LocationSummary* locs = new(zone) LocationSummary( 2487 LocationSummary* locs = new (zone)
2490 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2488 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2491 locs->set_in(0, Location::RegisterLocation(T0)); 2489 locs->set_in(0, Location::RegisterLocation(T0));
2492 locs->set_out(0, Location::RegisterLocation(T0)); 2490 locs->set_out(0, Location::RegisterLocation(T0));
2493 return locs; 2491 return locs;
2494 } 2492 }
2495 2493
2496 2494
2497 void InstantiateTypeArgumentsInstr::EmitNativeCode( 2495 void InstantiateTypeArgumentsInstr::EmitNativeCode(
2498 FlowGraphCompiler* compiler) { 2496 FlowGraphCompiler* compiler) {
2499 __ Comment("InstantiateTypeArgumentsInstr"); 2497 __ Comment("InstantiateTypeArgumentsInstr");
2500 Register instantiator_reg = locs()->in(0).reg(); 2498 Register instantiator_reg = locs()->in(0).reg();
(...skipping 17 matching lines...) Expand all
2518 2516
2519 __ LoadObject(T2, type_arguments()); 2517 __ LoadObject(T2, type_arguments());
2520 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); 2518 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset()));
2521 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); 2519 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag);
2522 // The instantiations cache is initialized with Object::zero_array() and is 2520 // The instantiations cache is initialized with Object::zero_array() and is
2523 // therefore guaranteed to contain kNoInstantiator. No length check needed. 2521 // therefore guaranteed to contain kNoInstantiator. No length check needed.
2524 Label loop, found, slow_case; 2522 Label loop, found, slow_case;
2525 __ Bind(&loop); 2523 __ Bind(&loop);
2526 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. 2524 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator.
2527 __ beq(T1, T0, &found); 2525 __ beq(T1, T0, &found);
2528 __ BranchNotEqual( 2526 __ BranchNotEqual(T1, Immediate(Smi::RawValue(StubCode::kNoInstantiator)),
2529 T1, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), &loop); 2527 &loop);
2530 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); 2528 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize));
2531 __ b(&slow_case); 2529 __ b(&slow_case);
2532 __ Bind(&found); 2530 __ Bind(&found);
2533 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. 2531 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args.
2534 __ b(&type_arguments_instantiated); 2532 __ b(&type_arguments_instantiated);
2535 2533
2536 __ Bind(&slow_case); 2534 __ Bind(&slow_case);
2537 // Instantiate non-null type arguments. 2535 // Instantiate non-null type arguments.
2538 // A runtime call to instantiate the type arguments is required. 2536 // A runtime call to instantiate the type arguments is required.
2539 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 2537 __ addiu(SP, SP, Immediate(-3 * kWordSize));
2540 __ LoadObject(TMP, Object::null_object()); 2538 __ LoadObject(TMP, Object::null_object());
2541 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. 2539 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result.
2542 __ LoadObject(TMP, type_arguments()); 2540 __ LoadObject(TMP, type_arguments());
2543 __ sw(TMP, Address(SP, 1 * kWordSize)); 2541 __ sw(TMP, Address(SP, 1 * kWordSize));
2544 // Push instantiator type arguments. 2542 // Push instantiator type arguments.
2545 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); 2543 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
2546 2544
2547 compiler->GenerateRuntimeCall(token_pos(), 2545 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2548 deopt_id(), 2546 kInstantiateTypeArgumentsRuntimeEntry, 2,
2549 kInstantiateTypeArgumentsRuntimeEntry,
2550 2,
2551 locs()); 2547 locs());
2552 // Pop instantiated type arguments. 2548 // Pop instantiated type arguments.
2553 __ lw(result_reg, Address(SP, 2 * kWordSize)); 2549 __ lw(result_reg, Address(SP, 2 * kWordSize));
2554 // Drop instantiator and uninstantiated type arguments. 2550 // Drop instantiator and uninstantiated type arguments.
2555 __ addiu(SP, SP, Immediate(3 * kWordSize)); 2551 __ addiu(SP, SP, Immediate(3 * kWordSize));
2556 __ Bind(&type_arguments_instantiated); 2552 __ Bind(&type_arguments_instantiated);
2557 } 2553 }
2558 2554
2559 2555
2560 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( 2556 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
2561 Zone* zone, 2557 Zone* zone,
2562 bool opt) const { 2558 bool opt) const {
2563 ASSERT(opt); 2559 ASSERT(opt);
2564 const intptr_t kNumInputs = 0; 2560 const intptr_t kNumInputs = 0;
2565 const intptr_t kNumTemps = 3; 2561 const intptr_t kNumTemps = 3;
2566 LocationSummary* locs = new(zone) LocationSummary( 2562 LocationSummary* locs = new (zone) LocationSummary(
2567 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 2563 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2568 locs->set_temp(0, Location::RegisterLocation(T1)); 2564 locs->set_temp(0, Location::RegisterLocation(T1));
2569 locs->set_temp(1, Location::RegisterLocation(T2)); 2565 locs->set_temp(1, Location::RegisterLocation(T2));
2570 locs->set_temp(2, Location::RegisterLocation(T3)); 2566 locs->set_temp(2, Location::RegisterLocation(T3));
2571 locs->set_out(0, Location::RegisterLocation(V0)); 2567 locs->set_out(0, Location::RegisterLocation(V0));
2572 return locs; 2568 return locs;
2573 } 2569 }
2574 2570
2575 2571
2576 class AllocateContextSlowPath : public SlowPathCode { 2572 class AllocateContextSlowPath : public SlowPathCode {
2577 public: 2573 public:
2578 explicit AllocateContextSlowPath( 2574 explicit AllocateContextSlowPath(
2579 AllocateUninitializedContextInstr* instruction) 2575 AllocateUninitializedContextInstr* instruction)
2580 : instruction_(instruction) { } 2576 : instruction_(instruction) {}
2581 2577
2582 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2578 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2583 __ Comment("AllocateContextSlowPath"); 2579 __ Comment("AllocateContextSlowPath");
2584 __ Bind(entry_label()); 2580 __ Bind(entry_label());
2585 2581
2586 LocationSummary* locs = instruction_->locs(); 2582 LocationSummary* locs = instruction_->locs();
2587 locs->live_registers()->Remove(locs->out(0)); 2583 locs->live_registers()->Remove(locs->out(0));
2588 2584
2589 compiler->SaveLiveRegisters(locs); 2585 compiler->SaveLiveRegisters(locs);
2590 2586
2591 __ LoadImmediate(T1, instruction_->num_context_variables()); 2587 __ LoadImmediate(T1, instruction_->num_context_variables());
2592 const Code& stub = Code::ZoneHandle( 2588 const Code& stub = Code::ZoneHandle(
2593 compiler->zone(), StubCode::AllocateContext_entry()->code()); 2589 compiler->zone(), StubCode::AllocateContext_entry()->code());
2594 compiler->AddStubCallTarget(stub); 2590 compiler->AddStubCallTarget(stub);
2595 compiler->GenerateCall(instruction_->token_pos(), 2591 compiler->GenerateCall(instruction_->token_pos(),
2596 *StubCode::AllocateContext_entry(), 2592 *StubCode::AllocateContext_entry(),
2597 RawPcDescriptors::kOther, 2593 RawPcDescriptors::kOther, locs);
2598 locs);
2599 ASSERT(instruction_->locs()->out(0).reg() == V0); 2594 ASSERT(instruction_->locs()->out(0).reg() == V0);
2600 compiler->RestoreLiveRegisters(instruction_->locs()); 2595 compiler->RestoreLiveRegisters(instruction_->locs());
2601 __ b(exit_label()); 2596 __ b(exit_label());
2602 } 2597 }
2603 2598
2604 private: 2599 private:
2605 AllocateUninitializedContextInstr* instruction_; 2600 AllocateUninitializedContextInstr* instruction_;
2606 }; 2601 };
2607 2602
2608 2603
2609 void AllocateUninitializedContextInstr::EmitNativeCode( 2604 void AllocateUninitializedContextInstr::EmitNativeCode(
2610 FlowGraphCompiler* compiler) { 2605 FlowGraphCompiler* compiler) {
2611 Register temp0 = locs()->temp(0).reg(); 2606 Register temp0 = locs()->temp(0).reg();
2612 Register temp1 = locs()->temp(1).reg(); 2607 Register temp1 = locs()->temp(1).reg();
2613 Register temp2 = locs()->temp(2).reg(); 2608 Register temp2 = locs()->temp(2).reg();
2614 Register result = locs()->out(0).reg(); 2609 Register result = locs()->out(0).reg();
2615 // Try allocate the object. 2610 // Try allocate the object.
2616 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this); 2611 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
2617 compiler->AddSlowPathCode(slow_path); 2612 compiler->AddSlowPathCode(slow_path);
2618 intptr_t instance_size = Context::InstanceSize(num_context_variables()); 2613 intptr_t instance_size = Context::InstanceSize(num_context_variables());
2619 2614
2620 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(), 2615 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
2621 result, // instance 2616 result, // instance
2622 temp0, 2617 temp0, temp1, temp2);
2623 temp1,
2624 temp2);
2625 2618
2626 // Setup up number of context variables field. 2619 // Setup up number of context variables field.
2627 __ LoadImmediate(temp0, num_context_variables()); 2620 __ LoadImmediate(temp0, num_context_variables());
2628 __ sw(temp0, FieldAddress(result, Context::num_variables_offset())); 2621 __ sw(temp0, FieldAddress(result, Context::num_variables_offset()));
2629 2622
2630 __ Bind(slow_path->exit_label()); 2623 __ Bind(slow_path->exit_label());
2631 } 2624 }
2632 2625
2633 2626
2634 LocationSummary* AllocateContextInstr::MakeLocationSummary(Zone* zone, 2627 LocationSummary* AllocateContextInstr::MakeLocationSummary(Zone* zone,
2635 bool opt) const { 2628 bool opt) const {
2636 const intptr_t kNumInputs = 0; 2629 const intptr_t kNumInputs = 0;
2637 const intptr_t kNumTemps = 1; 2630 const intptr_t kNumTemps = 1;
2638 LocationSummary* locs = new(zone) LocationSummary( 2631 LocationSummary* locs = new (zone)
2639 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2632 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2640 locs->set_temp(0, Location::RegisterLocation(T1)); 2633 locs->set_temp(0, Location::RegisterLocation(T1));
2641 locs->set_out(0, Location::RegisterLocation(V0)); 2634 locs->set_out(0, Location::RegisterLocation(V0));
2642 return locs; 2635 return locs;
2643 } 2636 }
2644 2637
2645 2638
2646 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2639 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2647 ASSERT(locs()->temp(0).reg() == T1); 2640 ASSERT(locs()->temp(0).reg() == T1);
2648 ASSERT(locs()->out(0).reg() == V0); 2641 ASSERT(locs()->out(0).reg() == V0);
2649 2642
2650 __ Comment("AllocateContextInstr"); 2643 __ Comment("AllocateContextInstr");
2651 __ LoadImmediate(T1, num_context_variables()); 2644 __ LoadImmediate(T1, num_context_variables());
2652 compiler->GenerateCall(token_pos(), 2645 compiler->GenerateCall(token_pos(), *StubCode::AllocateContext_entry(),
2653 *StubCode::AllocateContext_entry(), 2646 RawPcDescriptors::kOther, locs());
2654 RawPcDescriptors::kOther,
2655 locs());
2656 } 2647 }
2657 2648
2658 2649
2659 LocationSummary* InitStaticFieldInstr::MakeLocationSummary(Zone* zone, 2650 LocationSummary* InitStaticFieldInstr::MakeLocationSummary(Zone* zone,
2660 bool opt) const { 2651 bool opt) const {
2661 const intptr_t kNumInputs = 1; 2652 const intptr_t kNumInputs = 1;
2662 const intptr_t kNumTemps = 1; 2653 const intptr_t kNumTemps = 1;
2663 LocationSummary* locs = new(zone) LocationSummary( 2654 LocationSummary* locs = new (zone)
2664 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2655 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2665 locs->set_in(0, Location::RegisterLocation(T0)); 2656 locs->set_in(0, Location::RegisterLocation(T0));
2666 locs->set_temp(0, Location::RegisterLocation(T1)); 2657 locs->set_temp(0, Location::RegisterLocation(T1));
2667 return locs; 2658 return locs;
2668 } 2659 }
2669 2660
2670 2661
2671 void InitStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2662 void InitStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2672 Register field = locs()->in(0).reg(); 2663 Register field = locs()->in(0).reg();
2673 Register temp = locs()->temp(0).reg(); 2664 Register temp = locs()->temp(0).reg();
2674 2665
2675 Label call_runtime, no_call; 2666 Label call_runtime, no_call;
2676 __ Comment("InitStaticFieldInstr"); 2667 __ Comment("InitStaticFieldInstr");
2677 2668
2678 __ lw(temp, FieldAddress(field, Field::static_value_offset())); 2669 __ lw(temp, FieldAddress(field, Field::static_value_offset()));
2679 __ BranchEqual(temp, Object::sentinel(), &call_runtime); 2670 __ BranchEqual(temp, Object::sentinel(), &call_runtime);
2680 __ BranchNotEqual(temp, Object::transition_sentinel(), &no_call); 2671 __ BranchNotEqual(temp, Object::transition_sentinel(), &no_call);
2681 2672
2682 __ Bind(&call_runtime); 2673 __ Bind(&call_runtime);
2683 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 2674 __ addiu(SP, SP, Immediate(-2 * kWordSize));
2684 __ LoadObject(TMP, Object::null_object()); 2675 __ LoadObject(TMP, Object::null_object());
2685 __ sw(TMP, Address(SP, 1 * kWordSize)); // Make room for (unused) result. 2676 __ sw(TMP, Address(SP, 1 * kWordSize)); // Make room for (unused) result.
2686 __ sw(field, Address(SP, 0 * kWordSize)); 2677 __ sw(field, Address(SP, 0 * kWordSize));
2687 2678
2688 compiler->GenerateRuntimeCall(token_pos(), 2679 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2689 deopt_id(), 2680 kInitStaticFieldRuntimeEntry, 1, locs());
2690 kInitStaticFieldRuntimeEntry,
2691 1,
2692 locs());
2693 2681
2694 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Purge argument and result. 2682 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Purge argument and result.
2695 2683
2696 __ Bind(&no_call); 2684 __ Bind(&no_call);
2697 } 2685 }
2698 2686
2699 2687
2700 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone, 2688 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
2701 bool opt) const { 2689 bool opt) const {
2702 const intptr_t kNumInputs = 1; 2690 const intptr_t kNumInputs = 1;
2703 const intptr_t kNumTemps = 0; 2691 const intptr_t kNumTemps = 0;
2704 LocationSummary* locs = new(zone) LocationSummary( 2692 LocationSummary* locs = new (zone)
2705 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2693 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2706 locs->set_in(0, Location::RegisterLocation(T0)); 2694 locs->set_in(0, Location::RegisterLocation(T0));
2707 locs->set_out(0, Location::RegisterLocation(T0)); 2695 locs->set_out(0, Location::RegisterLocation(T0));
2708 return locs; 2696 return locs;
2709 } 2697 }
2710 2698
2711 2699
2712 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2700 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2713 Register context_value = locs()->in(0).reg(); 2701 Register context_value = locs()->in(0).reg();
2714 Register result = locs()->out(0).reg(); 2702 Register result = locs()->out(0).reg();
2715 2703
2716 __ Comment("CloneContextInstr"); 2704 __ Comment("CloneContextInstr");
2717 2705
2718 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 2706 __ addiu(SP, SP, Immediate(-2 * kWordSize));
2719 __ LoadObject(TMP, Object::null_object()); // Make room for the result. 2707 __ LoadObject(TMP, Object::null_object()); // Make room for the result.
2720 __ sw(TMP, Address(SP, 1 * kWordSize)); 2708 __ sw(TMP, Address(SP, 1 * kWordSize));
2721 __ sw(context_value, Address(SP, 0 * kWordSize)); 2709 __ sw(context_value, Address(SP, 0 * kWordSize));
2722 2710
2723 compiler->GenerateRuntimeCall(token_pos(), 2711 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2724 deopt_id(), 2712 kCloneContextRuntimeEntry, 1, locs());
2725 kCloneContextRuntimeEntry,
2726 1,
2727 locs());
2728 __ lw(result, Address(SP, 1 * kWordSize)); // Get result (cloned context). 2713 __ lw(result, Address(SP, 1 * kWordSize)); // Get result (cloned context).
2729 __ addiu(SP, SP, Immediate(2 * kWordSize)); 2714 __ addiu(SP, SP, Immediate(2 * kWordSize));
2730 } 2715 }
2731 2716
2732 2717
2733 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone, 2718 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
2734 bool opt) const { 2719 bool opt) const {
2735 UNREACHABLE(); 2720 UNREACHABLE();
2736 return NULL; 2721 return NULL;
2737 } 2722 }
2738 2723
2739 2724
2740 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2725 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2741 __ Bind(compiler->GetJumpLabel(this)); 2726 __ Bind(compiler->GetJumpLabel(this));
2742 compiler->AddExceptionHandler(catch_try_index(), 2727 compiler->AddExceptionHandler(catch_try_index(), try_index(),
2743 try_index(),
2744 compiler->assembler()->CodeSize(), 2728 compiler->assembler()->CodeSize(),
2745 catch_handler_types_, 2729 catch_handler_types_, needs_stacktrace());
2746 needs_stacktrace());
2747 // On lazy deoptimization we patch the optimized code here to enter the 2730 // On lazy deoptimization we patch the optimized code here to enter the
2748 // deoptimization stub. 2731 // deoptimization stub.
2749 const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); 2732 const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
2750 if (compiler->is_optimizing()) { 2733 if (compiler->is_optimizing()) {
2751 compiler->AddDeoptIndexAtCall(deopt_id); 2734 compiler->AddDeoptIndexAtCall(deopt_id);
2752 } else { 2735 } else {
2753 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, 2736 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
2754 deopt_id,
2755 TokenPosition::kNoSource); 2737 TokenPosition::kNoSource);
2756 } 2738 }
2757 if (HasParallelMove()) { 2739 if (HasParallelMove()) {
2758 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 2740 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
2759 } 2741 }
2760 // Restore SP from FP as we are coming from a throw and the code for 2742 // Restore SP from FP as we are coming from a throw and the code for
2761 // popping arguments has not been run. 2743 // popping arguments has not been run.
2762 const intptr_t fp_sp_dist = 2744 const intptr_t fp_sp_dist =
2763 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; 2745 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
2764 ASSERT(fp_sp_dist <= 0); 2746 ASSERT(fp_sp_dist <= 0);
2765 __ AddImmediate(SP, FP, fp_sp_dist); 2747 __ AddImmediate(SP, FP, fp_sp_dist);
2766 2748
2767 // Restore stack and initialize the two exception variables: 2749 // Restore stack and initialize the two exception variables:
2768 // exception and stack trace variables. 2750 // exception and stack trace variables.
2769 __ StoreToOffset(kExceptionObjectReg, 2751 __ StoreToOffset(kExceptionObjectReg, FP,
2770 FP, exception_var().index() * kWordSize); 2752 exception_var().index() * kWordSize);
2771 __ StoreToOffset(kStackTraceObjectReg, 2753 __ StoreToOffset(kStackTraceObjectReg, FP,
2772 FP, stacktrace_var().index() * kWordSize); 2754 stacktrace_var().index() * kWordSize);
2773 } 2755 }
2774 2756
2775 2757
2776 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(Zone* zone, 2758 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(Zone* zone,
2777 bool opt) const { 2759 bool opt) const {
2778 const intptr_t kNumInputs = 0; 2760 const intptr_t kNumInputs = 0;
2779 const intptr_t kNumTemps = 1; 2761 const intptr_t kNumTemps = 1;
2780 LocationSummary* summary = new(zone) LocationSummary( 2762 LocationSummary* summary = new (zone) LocationSummary(
2781 zone, kNumInputs, 2763 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2782 kNumTemps,
2783 LocationSummary::kCallOnSlowPath);
2784 summary->set_temp(0, Location::RequiresRegister()); 2764 summary->set_temp(0, Location::RequiresRegister());
2785 return summary; 2765 return summary;
2786 } 2766 }
2787 2767
2788 2768
2789 class CheckStackOverflowSlowPath : public SlowPathCode { 2769 class CheckStackOverflowSlowPath : public SlowPathCode {
2790 public: 2770 public:
2791 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) 2771 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction)
2792 : instruction_(instruction) { } 2772 : instruction_(instruction) {}
2793 2773
2794 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2774 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2795 if (FLAG_use_osr && osr_entry_label()->IsLinked()) { 2775 if (FLAG_use_osr && osr_entry_label()->IsLinked()) {
2796 Register value = instruction_->locs()->temp(0).reg(); 2776 Register value = instruction_->locs()->temp(0).reg();
2797 __ Comment("CheckStackOverflowSlowPathOsr"); 2777 __ Comment("CheckStackOverflowSlowPathOsr");
2798 __ Bind(osr_entry_label()); 2778 __ Bind(osr_entry_label());
2799 __ LoadImmediate(value, Thread::kOsrRequest); 2779 __ LoadImmediate(value, Thread::kOsrRequest);
2800 __ sw(value, Address(THR, Thread::stack_overflow_flags_offset())); 2780 __ sw(value, Address(THR, Thread::stack_overflow_flags_offset()));
2801 } 2781 }
2802 __ Comment("CheckStackOverflowSlowPath"); 2782 __ Comment("CheckStackOverflowSlowPath");
2803 __ Bind(entry_label()); 2783 __ Bind(entry_label());
2804 compiler->SaveLiveRegisters(instruction_->locs()); 2784 compiler->SaveLiveRegisters(instruction_->locs());
2805 // pending_deoptimization_env_ is needed to generate a runtime call that 2785 // pending_deoptimization_env_ is needed to generate a runtime call that
2806 // may throw an exception. 2786 // may throw an exception.
2807 ASSERT(compiler->pending_deoptimization_env_ == NULL); 2787 ASSERT(compiler->pending_deoptimization_env_ == NULL);
2808 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); 2788 Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
2809 compiler->pending_deoptimization_env_ = env; 2789 compiler->pending_deoptimization_env_ = env;
2810 compiler->GenerateRuntimeCall(instruction_->token_pos(), 2790 compiler->GenerateRuntimeCall(
2811 instruction_->deopt_id(), 2791 instruction_->token_pos(), instruction_->deopt_id(),
2812 kStackOverflowRuntimeEntry, 2792 kStackOverflowRuntimeEntry, 0, instruction_->locs());
2813 0,
2814 instruction_->locs());
2815 2793
2816 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { 2794 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) {
2817 // In unoptimized code, record loop stack checks as possible OSR entries. 2795 // In unoptimized code, record loop stack checks as possible OSR entries.
2818 compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry, 2796 compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
2819 instruction_->deopt_id(), 2797 instruction_->deopt_id(),
2820 TokenPosition::kNoSource); 2798 TokenPosition::kNoSource);
2821 } 2799 }
2822 compiler->pending_deoptimization_env_ = NULL; 2800 compiler->pending_deoptimization_env_ = NULL;
2823 compiler->RestoreLiveRegisters(instruction_->locs()); 2801 compiler->RestoreLiveRegisters(instruction_->locs());
2824 __ b(exit_label()); 2802 __ b(exit_label());
(...skipping 19 matching lines...) Expand all
2844 __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label()); 2822 __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label());
2845 if (compiler->CanOSRFunction() && in_loop()) { 2823 if (compiler->CanOSRFunction() && in_loop()) {
2846 Register temp = locs()->temp(0).reg(); 2824 Register temp = locs()->temp(0).reg();
2847 // In unoptimized code check the usage counter to trigger OSR at loop 2825 // In unoptimized code check the usage counter to trigger OSR at loop
2848 // stack checks. Use progressively higher thresholds for more deeply 2826 // stack checks. Use progressively higher thresholds for more deeply
2849 // nested loops to attempt to hit outer loops with OSR when possible. 2827 // nested loops to attempt to hit outer loops with OSR when possible.
2850 __ LoadObject(temp, compiler->parsed_function().function()); 2828 __ LoadObject(temp, compiler->parsed_function().function());
2851 intptr_t threshold = 2829 intptr_t threshold =
2852 FLAG_optimization_counter_threshold * (loop_depth() + 1); 2830 FLAG_optimization_counter_threshold * (loop_depth() + 1);
2853 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset())); 2831 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset()));
2854 __ BranchSignedGreaterEqual( 2832 __ BranchSignedGreaterEqual(temp, Immediate(threshold),
2855 temp, Immediate(threshold), slow_path->osr_entry_label()); 2833 slow_path->osr_entry_label());
2856 } 2834 }
2857 if (compiler->ForceSlowPathForStackOverflow()) { 2835 if (compiler->ForceSlowPathForStackOverflow()) {
2858 __ b(slow_path->entry_label()); 2836 __ b(slow_path->entry_label());
2859 } 2837 }
2860 __ Bind(slow_path->exit_label()); 2838 __ Bind(slow_path->exit_label());
2861 } 2839 }
2862 2840
2863 2841
2864 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2842 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2865 BinarySmiOpInstr* shift_left) { 2843 BinarySmiOpInstr* shift_left) {
2866 const LocationSummary& locs = *shift_left->locs(); 2844 const LocationSummary& locs = *shift_left->locs();
2867 Register left = locs.in(0).reg(); 2845 Register left = locs.in(0).reg();
2868 Register result = locs.out(0).reg(); 2846 Register result = locs.out(0).reg();
2869 Label* deopt = shift_left->CanDeoptimize() ? 2847 Label* deopt = shift_left->CanDeoptimize()
2870 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) 2848 ? compiler->AddDeoptStub(shift_left->deopt_id(),
2871 : NULL; 2849 ICData::kDeoptBinarySmiOp)
2850 : NULL;
2872 2851
2873 __ Comment("EmitSmiShiftLeft"); 2852 __ Comment("EmitSmiShiftLeft");
2874 2853
2875 if (locs.in(1).IsConstant()) { 2854 if (locs.in(1).IsConstant()) {
2876 const Object& constant = locs.in(1).constant(); 2855 const Object& constant = locs.in(1).constant();
2877 ASSERT(constant.IsSmi()); 2856 ASSERT(constant.IsSmi());
2878 // Immediate shift operation takes 5 bits for the count. 2857 // Immediate shift operation takes 5 bits for the count.
2879 const intptr_t kCountLimit = 0x1F; 2858 const intptr_t kCountLimit = 0x1F;
2880 const intptr_t value = Smi::Cast(constant).Value(); 2859 const intptr_t value = Smi::Cast(constant).Value();
2881 ASSERT((0 < value) && (value < kCountLimit)); 2860 ASSERT((0 < value) && (value < kCountLimit));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2923 if (!shift_left->can_overflow()) { 2902 if (!shift_left->can_overflow()) {
2924 if (right_needs_check) { 2903 if (right_needs_check) {
2925 const bool right_may_be_negative = 2904 const bool right_may_be_negative =
2926 (right_range == NULL) || !right_range->IsPositive(); 2905 (right_range == NULL) || !right_range->IsPositive();
2927 if (right_may_be_negative) { 2906 if (right_may_be_negative) {
2928 ASSERT(shift_left->CanDeoptimize()); 2907 ASSERT(shift_left->CanDeoptimize());
2929 __ bltz(right, deopt); 2908 __ bltz(right, deopt);
2930 } 2909 }
2931 Label done, is_not_zero; 2910 Label done, is_not_zero;
2932 2911
2933 __ sltiu(CMPRES1, 2912 __ sltiu(CMPRES1, right,
2934 right, Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits)))); 2913 Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
2935 __ movz(result, ZR, CMPRES1); // result = right >= kBits ? 0 : result. 2914 __ movz(result, ZR, CMPRES1); // result = right >= kBits ? 0 : result.
2936 __ sra(TMP, right, kSmiTagSize); 2915 __ sra(TMP, right, kSmiTagSize);
2937 __ sllv(TMP, left, TMP); 2916 __ sllv(TMP, left, TMP);
2938 // result = right < kBits ? left << right : result. 2917 // result = right < kBits ? left << right : result.
2939 __ movn(result, TMP, CMPRES1); 2918 __ movn(result, TMP, CMPRES1);
2940 } else { 2919 } else {
2941 __ sra(TMP, right, kSmiTagSize); 2920 __ sra(TMP, right, kSmiTagSize);
2942 __ sllv(result, left, TMP); 2921 __ sllv(result, left, TMP);
2943 } 2922 }
2944 } else { 2923 } else {
(...skipping 13 matching lines...) Expand all
2958 __ bne(CMPRES1, left, deopt); // Overflow. 2937 __ bne(CMPRES1, left, deopt); // Overflow.
2959 // Shift for result now we know there is no overflow. 2938 // Shift for result now we know there is no overflow.
2960 __ sllv(result, left, temp); 2939 __ sllv(result, left, temp);
2961 } 2940 }
2962 } 2941 }
2963 2942
2964 2943
2965 class CheckedSmiSlowPath : public SlowPathCode { 2944 class CheckedSmiSlowPath : public SlowPathCode {
2966 public: 2945 public:
2967 CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index) 2946 CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index)
2968 : instruction_(instruction), try_index_(try_index) { } 2947 : instruction_(instruction), try_index_(try_index) {}
2969 2948
2970 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2949 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2971 if (Assembler::EmittingComments()) { 2950 if (Assembler::EmittingComments()) {
2972 __ Comment("slow path smi operation"); 2951 __ Comment("slow path smi operation");
2973 } 2952 }
2974 __ Bind(entry_label()); 2953 __ Bind(entry_label());
2975 LocationSummary* locs = instruction_->locs(); 2954 LocationSummary* locs = instruction_->locs();
2976 Register result = locs->out(0).reg(); 2955 Register result = locs->out(0).reg();
2977 locs->live_registers()->Remove(Location::RegisterLocation(result)); 2956 locs->live_registers()->Remove(Location::RegisterLocation(result));
2978 2957
2979 compiler->SaveLiveRegisters(locs); 2958 compiler->SaveLiveRegisters(locs);
2980 __ Push(locs->in(0).reg()); 2959 __ Push(locs->in(0).reg());
2981 __ Push(locs->in(1).reg()); 2960 __ Push(locs->in(1).reg());
2982 compiler->EmitMegamorphicInstanceCall( 2961 compiler->EmitMegamorphicInstanceCall(
2983 *instruction_->call()->ic_data(), 2962 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(),
2984 instruction_->call()->ArgumentCount(), 2963 instruction_->call()->deopt_id(), instruction_->call()->token_pos(),
2985 instruction_->call()->deopt_id(), 2964 locs, try_index_,
2986 instruction_->call()->token_pos(),
2987 locs,
2988 try_index_,
2989 /* slow_path_argument_count = */ 2); 2965 /* slow_path_argument_count = */ 2);
2990 __ mov(result, V0); 2966 __ mov(result, V0);
2991 compiler->RestoreLiveRegisters(locs); 2967 compiler->RestoreLiveRegisters(locs);
2992 __ b(exit_label()); 2968 __ b(exit_label());
2993 } 2969 }
2994 2970
2995 private: 2971 private:
2996 CheckedSmiOpInstr* instruction_; 2972 CheckedSmiOpInstr* instruction_;
2997 intptr_t try_index_; 2973 intptr_t try_index_;
2998 }; 2974 };
2999 2975
3000 2976
3001 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, 2977 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone,
3002 bool opt) const { 2978 bool opt) const {
3003 const intptr_t kNumInputs = 2; 2979 const intptr_t kNumInputs = 2;
3004 const intptr_t kNumTemps = 0; 2980 const intptr_t kNumTemps = 0;
3005 LocationSummary* summary = new(zone) LocationSummary( 2981 LocationSummary* summary = new (zone) LocationSummary(
3006 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 2982 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3007 summary->set_in(0, Location::RequiresRegister()); 2983 summary->set_in(0, Location::RequiresRegister());
3008 summary->set_in(1, Location::RequiresRegister()); 2984 summary->set_in(1, Location::RequiresRegister());
3009 summary->set_out(0, Location::RequiresRegister()); 2985 summary->set_out(0, Location::RequiresRegister());
3010 return summary; 2986 return summary;
3011 } 2987 }
3012 2988
3013 2989
3014 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2990 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3015 CheckedSmiSlowPath* slow_path = 2991 CheckedSmiSlowPath* slow_path =
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3072 3048
3073 class CheckedSmiComparisonSlowPath : public SlowPathCode { 3049 class CheckedSmiComparisonSlowPath : public SlowPathCode {
3074 public: 3050 public:
3075 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, 3051 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction,
3076 intptr_t try_index, 3052 intptr_t try_index,
3077 BranchLabels labels, 3053 BranchLabels labels,
3078 bool merged) 3054 bool merged)
3079 : instruction_(instruction), 3055 : instruction_(instruction),
3080 try_index_(try_index), 3056 try_index_(try_index),
3081 labels_(labels), 3057 labels_(labels),
3082 merged_(merged) { } 3058 merged_(merged) {}
3083 3059
3084 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 3060 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
3085 if (Assembler::EmittingComments()) { 3061 if (Assembler::EmittingComments()) {
3086 __ Comment("slow path smi operation"); 3062 __ Comment("slow path smi operation");
3087 } 3063 }
3088 __ Bind(entry_label()); 3064 __ Bind(entry_label());
3089 LocationSummary* locs = instruction_->locs(); 3065 LocationSummary* locs = instruction_->locs();
3090 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); 3066 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg();
3091 locs->live_registers()->Remove(Location::RegisterLocation(result)); 3067 locs->live_registers()->Remove(Location::RegisterLocation(result));
3092 3068
3093 compiler->SaveLiveRegisters(locs); 3069 compiler->SaveLiveRegisters(locs);
3094 __ Push(locs->in(0).reg()); 3070 __ Push(locs->in(0).reg());
3095 __ Push(locs->in(1).reg()); 3071 __ Push(locs->in(1).reg());
3096 compiler->EmitMegamorphicInstanceCall( 3072 compiler->EmitMegamorphicInstanceCall(
3097 *instruction_->call()->ic_data(), 3073 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(),
3098 instruction_->call()->ArgumentCount(), 3074 instruction_->call()->deopt_id(), instruction_->call()->token_pos(),
3099 instruction_->call()->deopt_id(), 3075 locs, try_index_,
3100 instruction_->call()->token_pos(),
3101 locs,
3102 try_index_,
3103 /* slow_path_argument_count = */ 2); 3076 /* slow_path_argument_count = */ 2);
3104 __ mov(result, V0); 3077 __ mov(result, V0);
3105 compiler->RestoreLiveRegisters(locs); 3078 compiler->RestoreLiveRegisters(locs);
3106 if (merged_) { 3079 if (merged_) {
3107 __ BranchEqual(result, Bool::True(), 3080 __ BranchEqual(result, Bool::True(), instruction_->is_negated()
3108 instruction_->is_negated() ? labels_.false_label : labels_.true_label); 3081 ? labels_.false_label
3109 __ b(instruction_->is_negated() 3082 : labels_.true_label);
3110 ? labels_.true_label : labels_.false_label); 3083 __ b(instruction_->is_negated() ? labels_.true_label
3084 : labels_.false_label);
3111 } else { 3085 } else {
3112 __ b(exit_label()); 3086 __ b(exit_label());
3113 } 3087 }
3114 } 3088 }
3115 3089
3116 private: 3090 private:
3117 CheckedSmiComparisonInstr* instruction_; 3091 CheckedSmiComparisonInstr* instruction_;
3118 intptr_t try_index_; 3092 intptr_t try_index_;
3119 BranchLabels labels_; 3093 BranchLabels labels_;
3120 bool merged_; 3094 bool merged_;
3121 }; 3095 };
3122 3096
3123 3097
3124 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary( 3098 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
3125 Zone* zone, bool opt) const { 3099 Zone* zone,
3100 bool opt) const {
3126 const intptr_t kNumInputs = 2; 3101 const intptr_t kNumInputs = 2;
3127 const intptr_t kNumTemps = 1; 3102 const intptr_t kNumTemps = 1;
3128 LocationSummary* summary = new(zone) LocationSummary( 3103 LocationSummary* summary = new (zone) LocationSummary(
3129 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3104 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3130 summary->set_in(0, Location::RequiresRegister()); 3105 summary->set_in(0, Location::RequiresRegister());
3131 summary->set_in(1, Location::RequiresRegister()); 3106 summary->set_in(1, Location::RequiresRegister());
3132 summary->set_temp(0, Location::RequiresRegister()); 3107 summary->set_temp(0, Location::RequiresRegister());
3133 summary->set_out(0, Location::RequiresRegister()); 3108 summary->set_out(0, Location::RequiresRegister());
3134 return summary; 3109 return summary;
3135 } 3110 }
3136 3111
3137 3112
3138 Condition CheckedSmiComparisonInstr::EmitComparisonCode( 3113 Condition CheckedSmiComparisonInstr::EmitComparisonCode(
3139 FlowGraphCompiler* compiler, BranchLabels labels) { 3114 FlowGraphCompiler* compiler,
3115 BranchLabels labels) {
3140 return EmitSmiComparisonOp(compiler, *locs(), kind()); 3116 return EmitSmiComparisonOp(compiler, *locs(), kind());
3141 } 3117 }
3142 3118
3143 3119
3144 #define EMIT_SMI_CHECK \ 3120 #define EMIT_SMI_CHECK \
3145 Register left = locs()->in(0).reg(); \ 3121 Register left = locs()->in(0).reg(); \
3146 Register right = locs()->in(1).reg(); \ 3122 Register right = locs()->in(1).reg(); \
3147 Register temp = locs()->temp(0).reg(); \ 3123 Register temp = locs()->temp(0).reg(); \
3148 intptr_t left_cid = this->left()->Type()->ToCid(); \ 3124 intptr_t left_cid = this->left()->Type()->ToCid(); \
3149 intptr_t right_cid = this->right()->Type()->ToCid(); \ 3125 intptr_t right_cid = this->right()->Type()->ToCid(); \
3150 if (this->left()->definition() == this->right()->definition()) { \ 3126 if (this->left()->definition() == this->right()->definition()) { \
3151 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \ 3127 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \
3152 } else if (left_cid == kSmiCid) { \ 3128 } else if (left_cid == kSmiCid) { \
3153 __ andi(CMPRES1, right, Immediate(kSmiTagMask)); \ 3129 __ andi(CMPRES1, right, Immediate(kSmiTagMask)); \
3154 } else if (right_cid == kSmiCid) { \ 3130 } else if (right_cid == kSmiCid) { \
3155 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \ 3131 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \
3156 } else { \ 3132 } else { \
3157 __ or_(temp, left, right); \ 3133 __ or_(temp, left, right); \
3158 __ andi(CMPRES1, temp, Immediate(kSmiTagMask)); \ 3134 __ andi(CMPRES1, temp, Immediate(kSmiTagMask)); \
3159 } \ 3135 } \
3160 __ bne(CMPRES1, ZR, slow_path->entry_label()); \ 3136 __ bne(CMPRES1, ZR, slow_path->entry_label());
3161 3137
3162 3138
3163 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 3139 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3164 BranchInstr* branch) { 3140 BranchInstr* branch) {
3165 BranchLabels labels = compiler->CreateBranchLabels(branch); 3141 BranchLabels labels = compiler->CreateBranchLabels(branch);
3166 CheckedSmiComparisonSlowPath* slow_path = 3142 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3167 new CheckedSmiComparisonSlowPath(this, 3143 this, compiler->CurrentTryIndex(), labels,
3168 compiler->CurrentTryIndex(), 3144 /* merged = */ true);
3169 labels,
3170 /* merged = */ true);
3171 compiler->AddSlowPathCode(slow_path); 3145 compiler->AddSlowPathCode(slow_path);
3172 EMIT_SMI_CHECK; 3146 EMIT_SMI_CHECK;
3173 Condition true_condition = EmitComparisonCode(compiler, labels); 3147 Condition true_condition = EmitComparisonCode(compiler, labels);
3174 EmitBranchOnCondition(compiler, true_condition, labels); 3148 EmitBranchOnCondition(compiler, true_condition, labels);
3175 __ Bind(slow_path->exit_label()); 3149 __ Bind(slow_path->exit_label());
3176 } 3150 }
3177 3151
3178 3152
3179 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3153 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3180 Label true_label, false_label, done; 3154 Label true_label, false_label, done;
3181 BranchLabels labels = { &true_label, &false_label, &false_label }; 3155 BranchLabels labels = {&true_label, &false_label, &false_label};
3182 CheckedSmiComparisonSlowPath* slow_path = 3156 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3183 new CheckedSmiComparisonSlowPath(this, 3157 this, compiler->CurrentTryIndex(), labels,
3184 compiler->CurrentTryIndex(), 3158 /* merged = */ false);
3185 labels,
3186 /* merged = */ false);
3187 compiler->AddSlowPathCode(slow_path); 3159 compiler->AddSlowPathCode(slow_path);
3188 EMIT_SMI_CHECK; 3160 EMIT_SMI_CHECK;
3189 Condition true_condition = EmitComparisonCode(compiler, labels); 3161 Condition true_condition = EmitComparisonCode(compiler, labels);
3190 EmitBranchOnCondition(compiler, true_condition, labels); 3162 EmitBranchOnCondition(compiler, true_condition, labels);
3191 Register result = locs()->out(0).reg(); 3163 Register result = locs()->out(0).reg();
3192 __ Bind(&false_label); 3164 __ Bind(&false_label);
3193 __ LoadObject(result, Bool::False()); 3165 __ LoadObject(result, Bool::False());
3194 __ b(&done); 3166 __ b(&done);
3195 __ Bind(&true_label); 3167 __ Bind(&true_label);
3196 __ LoadObject(result, Bool::True()); 3168 __ LoadObject(result, Bool::True());
3197 __ Bind(&done); 3169 __ Bind(&done);
3198 __ Bind(slow_path->exit_label()); 3170 __ Bind(slow_path->exit_label());
3199 } 3171 }
3200 3172
3201 3173
3202 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, 3174 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
3203 bool opt) const { 3175 bool opt) const {
3204 const intptr_t kNumInputs = 2; 3176 const intptr_t kNumInputs = 2;
3205 const intptr_t kNumTemps = 3177 const intptr_t kNumTemps =
3206 ((op_kind() == Token::kADD) || 3178 ((op_kind() == Token::kADD) || (op_kind() == Token::kMOD) ||
3207 (op_kind() == Token::kMOD) ||
3208 (op_kind() == Token::kTRUNCDIV) || 3179 (op_kind() == Token::kTRUNCDIV) ||
3209 (((op_kind() == Token::kSHL) && can_overflow()) || 3180 (((op_kind() == Token::kSHL) && can_overflow()) ||
3210 (op_kind() == Token::kSHR))) ? 1 : 0; 3181 (op_kind() == Token::kSHR)))
3211 LocationSummary* summary = new(zone) LocationSummary( 3182 ? 1
3212 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3183 : 0;
3184 LocationSummary* summary = new (zone)
3185 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3213 if (op_kind() == Token::kTRUNCDIV) { 3186 if (op_kind() == Token::kTRUNCDIV) {
3214 summary->set_in(0, Location::RequiresRegister()); 3187 summary->set_in(0, Location::RequiresRegister());
3215 if (RightIsPowerOfTwoConstant()) { 3188 if (RightIsPowerOfTwoConstant()) {
3216 ConstantInstr* right_constant = right()->definition()->AsConstant(); 3189 ConstantInstr* right_constant = right()->definition()->AsConstant();
3217 summary->set_in(1, Location::Constant(right_constant)); 3190 summary->set_in(1, Location::Constant(right_constant));
3218 } else { 3191 } else {
3219 summary->set_in(1, Location::RequiresRegister()); 3192 summary->set_in(1, Location::RequiresRegister());
3220 } 3193 }
3221 summary->set_temp(0, Location::RequiresRegister()); 3194 summary->set_temp(0, Location::RequiresRegister());
3222 summary->set_out(0, Location::RequiresRegister()); 3195 summary->set_out(0, Location::RequiresRegister());
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3493 } 3466 }
3494 3467
3495 3468
3496 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone, 3469 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone,
3497 bool opt) const { 3470 bool opt) const {
3498 intptr_t left_cid = left()->Type()->ToCid(); 3471 intptr_t left_cid = left()->Type()->ToCid();
3499 intptr_t right_cid = right()->Type()->ToCid(); 3472 intptr_t right_cid = right()->Type()->ToCid();
3500 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); 3473 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
3501 const intptr_t kNumInputs = 2; 3474 const intptr_t kNumInputs = 2;
3502 const intptr_t kNumTemps = 0; 3475 const intptr_t kNumTemps = 0;
3503 LocationSummary* summary = new(zone) LocationSummary( 3476 LocationSummary* summary = new (zone)
3504 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3477 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3505 summary->set_in(0, Location::RequiresRegister()); 3478 summary->set_in(0, Location::RequiresRegister());
3506 summary->set_in(1, Location::RequiresRegister()); 3479 summary->set_in(1, Location::RequiresRegister());
3507 return summary; 3480 return summary;
3508 } 3481 }
3509 3482
3510 3483
3511 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3484 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3512 Label* deopt = compiler->AddDeoptStub(deopt_id(), 3485 Label* deopt =
3513 ICData::kDeoptBinaryDoubleOp, 3486 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryDoubleOp,
3514 licm_hoisted_ ? ICData::kHoisted : 0); 3487 licm_hoisted_ ? ICData::kHoisted : 0);
3515 intptr_t left_cid = left()->Type()->ToCid(); 3488 intptr_t left_cid = left()->Type()->ToCid();
3516 intptr_t right_cid = right()->Type()->ToCid(); 3489 intptr_t right_cid = right()->Type()->ToCid();
3517 Register left = locs()->in(0).reg(); 3490 Register left = locs()->in(0).reg();
3518 Register right = locs()->in(1).reg(); 3491 Register right = locs()->in(1).reg();
3519 if (this->left()->definition() == this->right()->definition()) { 3492 if (this->left()->definition() == this->right()->definition()) {
3520 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); 3493 __ andi(CMPRES1, left, Immediate(kSmiTagMask));
3521 } else if (left_cid == kSmiCid) { 3494 } else if (left_cid == kSmiCid) {
3522 __ andi(CMPRES1, right, Immediate(kSmiTagMask)); 3495 __ andi(CMPRES1, right, Immediate(kSmiTagMask));
3523 } else if (right_cid == kSmiCid) { 3496 } else if (right_cid == kSmiCid) {
3524 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); 3497 __ andi(CMPRES1, left, Immediate(kSmiTagMask));
3525 } else { 3498 } else {
3526 __ or_(TMP, left, right); 3499 __ or_(TMP, left, right);
3527 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); 3500 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask));
3528 } 3501 }
3529 __ beq(CMPRES1, ZR, deopt); 3502 __ beq(CMPRES1, ZR, deopt);
3530 } 3503 }
3531 3504
3532 3505
3533 LocationSummary* BoxInstr::MakeLocationSummary(Zone* zone, 3506 LocationSummary* BoxInstr::MakeLocationSummary(Zone* zone, bool opt) const {
3534 bool opt) const {
3535 const intptr_t kNumInputs = 1; 3507 const intptr_t kNumInputs = 1;
3536 const intptr_t kNumTemps = 1; 3508 const intptr_t kNumTemps = 1;
3537 LocationSummary* summary = new(zone) LocationSummary( 3509 LocationSummary* summary = new (zone) LocationSummary(
3538 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3510 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3539 summary->set_in(0, Location::RequiresFpuRegister()); 3511 summary->set_in(0, Location::RequiresFpuRegister());
3540 summary->set_temp(0, Location::RequiresRegister()); 3512 summary->set_temp(0, Location::RequiresRegister());
3541 summary->set_out(0, Location::RequiresRegister()); 3513 summary->set_out(0, Location::RequiresRegister());
3542 return summary; 3514 return summary;
3543 } 3515 }
3544 3516
3545 3517
3546 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3518 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3547 ASSERT(from_representation() == kUnboxedDouble); 3519 ASSERT(from_representation() == kUnboxedDouble);
3548 3520
3549 Register out_reg = locs()->out(0).reg(); 3521 Register out_reg = locs()->out(0).reg();
3550 DRegister value = locs()->in(0).fpu_reg(); 3522 DRegister value = locs()->in(0).fpu_reg();
3551 3523
3552 BoxAllocationSlowPath::Allocate( 3524 BoxAllocationSlowPath::Allocate(compiler, this, compiler->double_class(),
3553 compiler, this, compiler->double_class(), out_reg, locs()->temp(0).reg()); 3525 out_reg, locs()->temp(0).reg());
3554 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); 3526 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
3555 } 3527 }
3556 3528
3557 3529
3558 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, 3530 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const {
3559 bool opt) const {
3560 const intptr_t kNumInputs = 1; 3531 const intptr_t kNumInputs = 1;
3561 const intptr_t kNumTemps = 0; 3532 const intptr_t kNumTemps = 0;
3562 LocationSummary* summary = new(zone) LocationSummary( 3533 LocationSummary* summary = new (zone)
3563 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3534 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3564 summary->set_in(0, Location::RequiresRegister()); 3535 summary->set_in(0, Location::RequiresRegister());
3565 if (representation() == kUnboxedMint) { 3536 if (representation() == kUnboxedMint) {
3566 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 3537 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
3567 Location::RequiresRegister())); 3538 Location::RequiresRegister()));
3568 } else { 3539 } else {
3569 summary->set_out(0, Location::RequiresFpuRegister()); 3540 summary->set_out(0, Location::RequiresFpuRegister());
3570 } 3541 }
3571 return summary; 3542 return summary;
3572 } 3543 }
3573 3544
3574 3545
3575 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { 3546 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
3576 const Register box = locs()->in(0).reg(); 3547 const Register box = locs()->in(0).reg();
3577 3548
3578 switch (representation()) { 3549 switch (representation()) {
3579 case kUnboxedMint: { 3550 case kUnboxedMint: {
3580 PairLocation* result = locs()->out(0).AsPairLocation(); 3551 PairLocation* result = locs()->out(0).AsPairLocation();
3581 __ LoadFromOffset(result->At(0).reg(), 3552 __ LoadFromOffset(result->At(0).reg(), box,
3582 box,
3583 ValueOffset() - kHeapObjectTag); 3553 ValueOffset() - kHeapObjectTag);
3584 __ LoadFromOffset(result->At(1).reg(), 3554 __ LoadFromOffset(result->At(1).reg(), box,
3585 box,
3586 ValueOffset() - kHeapObjectTag + kWordSize); 3555 ValueOffset() - kHeapObjectTag + kWordSize);
3587 break; 3556 break;
3588 } 3557 }
3589 3558
3590 case kUnboxedDouble: { 3559 case kUnboxedDouble: {
3591 const DRegister result = locs()->out(0).fpu_reg(); 3560 const DRegister result = locs()->out(0).fpu_reg();
3592 __ LoadDFromOffset(result, box, Double::value_offset() - kHeapObjectTag); 3561 __ LoadDFromOffset(result, box, Double::value_offset() - kHeapObjectTag);
3593 break; 3562 break;
3594 } 3563 }
3595 3564
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3636 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3605 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3637 const intptr_t value_cid = value()->Type()->ToCid(); 3606 const intptr_t value_cid = value()->Type()->ToCid();
3638 const intptr_t box_cid = BoxCid(); 3607 const intptr_t box_cid = BoxCid();
3639 3608
3640 if (value_cid == box_cid) { 3609 if (value_cid == box_cid) {
3641 EmitLoadFromBox(compiler); 3610 EmitLoadFromBox(compiler);
3642 } else if (CanConvertSmi() && (value_cid == kSmiCid)) { 3611 } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
3643 EmitSmiConversion(compiler); 3612 EmitSmiConversion(compiler);
3644 } else { 3613 } else {
3645 const Register box = locs()->in(0).reg(); 3614 const Register box = locs()->in(0).reg();
3646 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), 3615 Label* deopt =
3647 ICData::kDeoptCheckClass); 3616 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
3648 Label is_smi; 3617 Label is_smi;
3649 3618
3650 if ((value()->Type()->ToNullableCid() == box_cid) && 3619 if ((value()->Type()->ToNullableCid() == box_cid) &&
3651 value()->Type()->is_nullable()) { 3620 value()->Type()->is_nullable()) {
3652 __ BranchEqual(box, Object::null_object(), deopt); 3621 __ BranchEqual(box, Object::null_object(), deopt);
3653 } else { 3622 } else {
3654 __ andi(CMPRES1, box, Immediate(kSmiTagMask)); 3623 __ andi(CMPRES1, box, Immediate(kSmiTagMask));
3655 __ beq(CMPRES1, ZR, CanConvertSmi() ? &is_smi : deopt); 3624 __ beq(CMPRES1, ZR, CanConvertSmi() ? &is_smi : deopt);
3656 __ LoadClassId(CMPRES1, box); 3625 __ LoadClassId(CMPRES1, box);
3657 __ BranchNotEqual(CMPRES1, Immediate(box_cid), deopt); 3626 __ BranchNotEqual(CMPRES1, Immediate(box_cid), deopt);
(...skipping 11 matching lines...) Expand all
3669 } 3638 }
3670 } 3639 }
3671 3640
3672 3641
3673 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone, 3642 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone,
3674 bool opt) const { 3643 bool opt) const {
3675 ASSERT((from_representation() == kUnboxedInt32) || 3644 ASSERT((from_representation() == kUnboxedInt32) ||
3676 (from_representation() == kUnboxedUint32)); 3645 (from_representation() == kUnboxedUint32));
3677 const intptr_t kNumInputs = 1; 3646 const intptr_t kNumInputs = 1;
3678 const intptr_t kNumTemps = 1; 3647 const intptr_t kNumTemps = 1;
3679 LocationSummary* summary = new(zone) LocationSummary( 3648 LocationSummary* summary = new (zone) LocationSummary(
3680 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3649 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3681 summary->set_in(0, Location::RequiresRegister()); 3650 summary->set_in(0, Location::RequiresRegister());
3682 summary->set_temp(0, Location::RequiresRegister()); 3651 summary->set_temp(0, Location::RequiresRegister());
3683 summary->set_out(0, Location::RequiresRegister()); 3652 summary->set_out(0, Location::RequiresRegister());
3684 return summary; 3653 return summary;
3685 } 3654 }
3686 3655
3687 3656
3688 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3657 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3689 Register value = locs()->in(0).reg(); 3658 Register value = locs()->in(0).reg();
3690 Register out = locs()->out(0).reg(); 3659 Register out = locs()->out(0).reg();
3691 ASSERT(value != out); 3660 ASSERT(value != out);
3692 3661
3693 __ SmiTag(out, value); 3662 __ SmiTag(out, value);
3694 if (!ValueFitsSmi()) { 3663 if (!ValueFitsSmi()) {
3695 Register temp = locs()->temp(0).reg(); 3664 Register temp = locs()->temp(0).reg();
3696 Label done; 3665 Label done;
3697 if (from_representation() == kUnboxedInt32) { 3666 if (from_representation() == kUnboxedInt32) {
3698 __ SmiUntag(CMPRES1, out); 3667 __ SmiUntag(CMPRES1, out);
3699 __ BranchEqual(CMPRES1, value, &done); 3668 __ BranchEqual(CMPRES1, value, &done);
3700 } else { 3669 } else {
3701 ASSERT(from_representation() == kUnboxedUint32); 3670 ASSERT(from_representation() == kUnboxedUint32);
3702 __ AndImmediate(CMPRES1, value, 0xC0000000); 3671 __ AndImmediate(CMPRES1, value, 0xC0000000);
3703 __ BranchEqual(CMPRES1, ZR, &done); 3672 __ BranchEqual(CMPRES1, ZR, &done);
3704 } 3673 }
3705 BoxAllocationSlowPath::Allocate( 3674 BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
3706 compiler, 3675 temp);
3707 this,
3708 compiler->mint_class(),
3709 out,
3710 temp);
3711 Register hi; 3676 Register hi;
3712 if (from_representation() == kUnboxedInt32) { 3677 if (from_representation() == kUnboxedInt32) {
3713 hi = temp; 3678 hi = temp;
3714 __ sra(hi, value, kBitsPerWord - 1); 3679 __ sra(hi, value, kBitsPerWord - 1);
3715 } else { 3680 } else {
3716 ASSERT(from_representation() == kUnboxedUint32); 3681 ASSERT(from_representation() == kUnboxedUint32);
3717 hi = ZR; 3682 hi = ZR;
3718 } 3683 }
3719 __ StoreToOffset(value, 3684 __ StoreToOffset(value, out, Mint::value_offset() - kHeapObjectTag);
3720 out, 3685 __ StoreToOffset(hi, out,
3721 Mint::value_offset() - kHeapObjectTag);
3722 __ StoreToOffset(hi,
3723 out,
3724 Mint::value_offset() - kHeapObjectTag + kWordSize); 3686 Mint::value_offset() - kHeapObjectTag + kWordSize);
3725 __ Bind(&done); 3687 __ Bind(&done);
3726 } 3688 }
3727 } 3689 }
3728 3690
3729 3691
3730 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone, 3692 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone,
3731 bool opt) const { 3693 bool opt) const {
3732 const intptr_t kNumInputs = 1; 3694 const intptr_t kNumInputs = 1;
3733 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; 3695 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
3734 LocationSummary* summary = new(zone) LocationSummary( 3696 LocationSummary* summary = new (zone)
3735 zone, 3697 LocationSummary(zone, kNumInputs, kNumTemps,
3736 kNumInputs, 3698 ValueFitsSmi() ? LocationSummary::kNoCall
3737 kNumTemps, 3699 : LocationSummary::kCallOnSlowPath);
3738 ValueFitsSmi() ? LocationSummary::kNoCall
3739 : LocationSummary::kCallOnSlowPath);
3740 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 3700 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
3741 Location::RequiresRegister())); 3701 Location::RequiresRegister()));
3742 if (!ValueFitsSmi()) { 3702 if (!ValueFitsSmi()) {
3743 summary->set_temp(0, Location::RequiresRegister()); 3703 summary->set_temp(0, Location::RequiresRegister());
3744 } 3704 }
3745 summary->set_out(0, Location::RequiresRegister()); 3705 summary->set_out(0, Location::RequiresRegister());
3746 return summary; 3706 return summary;
3747 } 3707 }
3748 3708
3749 3709
(...skipping 13 matching lines...) Expand all
3763 Register out_reg = locs()->out(0).reg(); 3723 Register out_reg = locs()->out(0).reg();
3764 3724
3765 Label not_smi, done; 3725 Label not_smi, done;
3766 __ SmiTag(out_reg, value_lo); 3726 __ SmiTag(out_reg, value_lo);
3767 __ SmiUntag(tmp, out_reg); 3727 __ SmiUntag(tmp, out_reg);
3768 __ bne(tmp, value_lo, &not_smi); 3728 __ bne(tmp, value_lo, &not_smi);
3769 __ delay_slot()->sra(tmp, out_reg, 31); 3729 __ delay_slot()->sra(tmp, out_reg, 31);
3770 __ beq(tmp, value_hi, &done); 3730 __ beq(tmp, value_hi, &done);
3771 3731
3772 __ Bind(&not_smi); 3732 __ Bind(&not_smi);
3773 BoxAllocationSlowPath::Allocate( 3733 BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
3774 compiler, 3734 out_reg, tmp);
3775 this,
3776 compiler->mint_class(),
3777 out_reg,
3778 tmp);
3779 __ StoreToOffset(value_lo, out_reg, Mint::value_offset() - kHeapObjectTag); 3735 __ StoreToOffset(value_lo, out_reg, Mint::value_offset() - kHeapObjectTag);
3780 __ StoreToOffset(value_hi, 3736 __ StoreToOffset(value_hi, out_reg,
3781 out_reg,
3782 Mint::value_offset() - kHeapObjectTag + kWordSize); 3737 Mint::value_offset() - kHeapObjectTag + kWordSize);
3783 __ Bind(&done); 3738 __ Bind(&done);
3784 } 3739 }
3785 3740
3786 3741
3787 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone, 3742 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,
3788 bool opt) const { 3743 bool opt) const {
3789 ASSERT((representation() == kUnboxedInt32) || 3744 ASSERT((representation() == kUnboxedInt32) ||
3790 (representation() == kUnboxedUint32)); 3745 (representation() == kUnboxedUint32));
3791 const intptr_t kNumInputs = 1; 3746 const intptr_t kNumInputs = 1;
3792 const intptr_t kNumTemps = 0; 3747 const intptr_t kNumTemps = 0;
3793 LocationSummary* summary = new(zone) LocationSummary( 3748 LocationSummary* summary = new (zone)
3794 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3749 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3795 summary->set_in(0, Location::RequiresRegister()); 3750 summary->set_in(0, Location::RequiresRegister());
3796 summary->set_out(0, Location::RequiresRegister()); 3751 summary->set_out(0, Location::RequiresRegister());
3797 return summary; 3752 return summary;
3798 } 3753 }
3799 3754
3800 3755
3801 static void LoadInt32FromMint(FlowGraphCompiler* compiler, 3756 static void LoadInt32FromMint(FlowGraphCompiler* compiler,
3802 Register mint, 3757 Register mint,
3803 Register result, 3758 Register result,
3804 Label* deopt) { 3759 Label* deopt) {
3805 __ LoadFieldFromOffset(result, mint, Mint::value_offset()); 3760 __ LoadFieldFromOffset(result, mint, Mint::value_offset());
3806 if (deopt != NULL) { 3761 if (deopt != NULL) {
3807 __ LoadFieldFromOffset(CMPRES1, 3762 __ LoadFieldFromOffset(CMPRES1, mint, Mint::value_offset() + kWordSize);
3808 mint,
3809 Mint::value_offset() + kWordSize);
3810 __ sra(CMPRES2, result, kBitsPerWord - 1); 3763 __ sra(CMPRES2, result, kBitsPerWord - 1);
3811 __ BranchNotEqual(CMPRES1, CMPRES2, deopt); 3764 __ BranchNotEqual(CMPRES1, CMPRES2, deopt);
3812 } 3765 }
3813 } 3766 }
3814 3767
3815 3768
3816 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3769 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3817 const intptr_t value_cid = value()->Type()->ToCid(); 3770 const intptr_t value_cid = value()->Type()->ToCid();
3818 const Register value = locs()->in(0).reg(); 3771 const Register value = locs()->in(0).reg();
3819 const Register out = locs()->out(0).reg(); 3772 const Register out = locs()->out(0).reg();
3820 Label* deopt = CanDeoptimize() ? 3773 Label* deopt =
3821 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; 3774 CanDeoptimize()
3775 ? compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger)
3776 : NULL;
3822 Label* out_of_range = !is_truncating() ? deopt : NULL; 3777 Label* out_of_range = !is_truncating() ? deopt : NULL;
3823 ASSERT(value != out); 3778 ASSERT(value != out);
3824 3779
3825 if (value_cid == kSmiCid) { 3780 if (value_cid == kSmiCid) {
3826 __ SmiUntag(out, value); 3781 __ SmiUntag(out, value);
3827 } else if (value_cid == kMintCid) { 3782 } else if (value_cid == kMintCid) {
3828 LoadInt32FromMint(compiler, value, out, out_of_range); 3783 LoadInt32FromMint(compiler, value, out, out_of_range);
3829 } else if (!CanDeoptimize()) { 3784 } else if (!CanDeoptimize()) {
3830 Label done; 3785 Label done;
3831 __ SmiUntag(out, value); 3786 __ SmiUntag(out, value);
(...skipping 11 matching lines...) Expand all
3843 LoadInt32FromMint(compiler, value, out, out_of_range); 3798 LoadInt32FromMint(compiler, value, out, out_of_range);
3844 __ Bind(&done); 3799 __ Bind(&done);
3845 } 3800 }
3846 } 3801 }
3847 3802
3848 3803
3849 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Zone* zone, 3804 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
3850 bool opt) const { 3805 bool opt) const {
3851 const intptr_t kNumInputs = 2; 3806 const intptr_t kNumInputs = 2;
3852 const intptr_t kNumTemps = 0; 3807 const intptr_t kNumTemps = 0;
3853 LocationSummary* summary = new(zone) LocationSummary( 3808 LocationSummary* summary = new (zone)
3854 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3809 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3855 summary->set_in(0, Location::RequiresFpuRegister()); 3810 summary->set_in(0, Location::RequiresFpuRegister());
3856 summary->set_in(1, Location::RequiresFpuRegister()); 3811 summary->set_in(1, Location::RequiresFpuRegister());
3857 summary->set_out(0, Location::RequiresFpuRegister()); 3812 summary->set_out(0, Location::RequiresFpuRegister());
3858 return summary; 3813 return summary;
3859 } 3814 }
3860 3815
3861 3816
3862 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3817 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3863 DRegister left = locs()->in(0).fpu_reg(); 3818 DRegister left = locs()->in(0).fpu_reg();
3864 DRegister right = locs()->in(1).fpu_reg(); 3819 DRegister right = locs()->in(1).fpu_reg();
3865 DRegister result = locs()->out(0).fpu_reg(); 3820 DRegister result = locs()->out(0).fpu_reg();
3866 switch (op_kind()) { 3821 switch (op_kind()) {
3867 case Token::kADD: __ addd(result, left, right); break; 3822 case Token::kADD:
3868 case Token::kSUB: __ subd(result, left, right); break; 3823 __ addd(result, left, right);
3869 case Token::kMUL: __ muld(result, left, right); break; 3824 break;
3870 case Token::kDIV: __ divd(result, left, right); break; 3825 case Token::kSUB:
3871 default: UNREACHABLE(); 3826 __ subd(result, left, right);
3827 break;
3828 case Token::kMUL:
3829 __ muld(result, left, right);
3830 break;
3831 case Token::kDIV:
3832 __ divd(result, left, right);
3833 break;
3834 default:
3835 UNREACHABLE();
3872 } 3836 }
3873 } 3837 }
3874 3838
3875 3839
3876 LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone, 3840 LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
3877 bool opt) const { 3841 bool opt) const {
3878 const intptr_t kNumInputs = 1; 3842 const intptr_t kNumInputs = 1;
3879 const intptr_t kNumTemps = 0; 3843 const intptr_t kNumTemps = 0;
3880 LocationSummary* summary = new(zone) LocationSummary( 3844 LocationSummary* summary = new (zone)
3881 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3845 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3882 summary->set_in(0, Location::RequiresFpuRegister()); 3846 summary->set_in(0, Location::RequiresFpuRegister());
3883 summary->set_out(0, Location::RequiresRegister()); 3847 summary->set_out(0, Location::RequiresRegister());
3884 return summary; 3848 return summary;
3885 } 3849 }
3886 3850
3887 3851
3888 Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 3852 Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
3889 BranchLabels labels) { 3853 BranchLabels labels) {
3890 const DRegister value = locs()->in(0).fpu_reg(); 3854 const DRegister value = locs()->in(0).fpu_reg();
3891 const bool is_negated = kind() != Token::kEQ; 3855 const bool is_negated = kind() != Token::kEQ;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3933 Condition true_condition = EmitComparisonCode(compiler, labels); 3897 Condition true_condition = EmitComparisonCode(compiler, labels);
3934 // Branches for isNaN are emitted in EmitComparisonCode already. 3898 // Branches for isNaN are emitted in EmitComparisonCode already.
3935 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { 3899 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) {
3936 EmitBranchOnCondition(compiler, true_condition, labels); 3900 EmitBranchOnCondition(compiler, true_condition, labels);
3937 } 3901 }
3938 } 3902 }
3939 3903
3940 3904
3941 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3905 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3942 Label is_true, is_false; 3906 Label is_true, is_false;
3943 BranchLabels labels = { &is_true, &is_false, &is_false }; 3907 BranchLabels labels = {&is_true, &is_false, &is_false};
3944 Condition true_condition = EmitComparisonCode(compiler, labels); 3908 Condition true_condition = EmitComparisonCode(compiler, labels);
3945 // Branches for isNaN are emitted in EmitComparisonCode already. 3909 // Branches for isNaN are emitted in EmitComparisonCode already.
3946 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { 3910 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) {
3947 EmitBranchOnCondition(compiler, true_condition, labels); 3911 EmitBranchOnCondition(compiler, true_condition, labels);
3948 } 3912 }
3949 const Register result = locs()->out(0).reg(); 3913 const Register result = locs()->out(0).reg();
3950 Label done; 3914 Label done;
3951 __ Comment("return bool"); 3915 __ Comment("return bool");
3952 __ Bind(&is_false); 3916 __ Bind(&is_false);
3953 __ LoadObject(result, Bool::False()); 3917 __ LoadObject(result, Bool::False());
3954 __ b(&done); 3918 __ b(&done);
3955 __ Bind(&is_true); 3919 __ Bind(&is_true);
3956 __ LoadObject(result, Bool::True()); 3920 __ LoadObject(result, Bool::True());
3957 __ Bind(&done); 3921 __ Bind(&done);
(...skipping 29 matching lines...) Expand all
3987 UNIMPLEMENTED(); 3951 UNIMPLEMENTED();
3988 return NULL; 3952 return NULL;
3989 } 3953 }
3990 3954
3991 3955
3992 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3956 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3993 UNIMPLEMENTED(); 3957 UNIMPLEMENTED();
3994 } 3958 }
3995 3959
3996 3960
3997
3998 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(Zone* zone, 3961 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(Zone* zone,
3999 bool opt) const { 3962 bool opt) const {
4000 UNIMPLEMENTED(); 3963 UNIMPLEMENTED();
4001 return NULL; 3964 return NULL;
4002 } 3965 }
4003 3966
4004 3967
4005 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3968 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4006 UNIMPLEMENTED(); 3969 UNIMPLEMENTED();
4007 } 3970 }
4008 3971
4009 3972
4010 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( 3973 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
4011 Zone* zone, bool opt) const { 3974 Zone* zone,
3975 bool opt) const {
4012 UNIMPLEMENTED(); 3976 UNIMPLEMENTED();
4013 return NULL; 3977 return NULL;
4014 } 3978 }
4015 3979
4016 3980
4017 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3981 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4018 UNIMPLEMENTED(); 3982 UNIMPLEMENTED();
4019 } 3983 }
4020 3984
4021 3985
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4140 4104
4141 4105
4142 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(Zone* zone, 4106 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(Zone* zone,
4143 bool opt) const { 4107 bool opt) const {
4144 UNIMPLEMENTED(); 4108 UNIMPLEMENTED();
4145 return NULL; 4109 return NULL;
4146 } 4110 }
4147 4111
4148 4112
4149 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4113 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4150 UNIMPLEMENTED(); 4114 UNIMPLEMENTED();
4151 } 4115 }
4152 4116
4153 4117
4154 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(Zone* zone, 4118 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(Zone* zone,
4155 bool opt) const { 4119 bool opt) const {
4156 UNIMPLEMENTED(); 4120 UNIMPLEMENTED();
4157 return NULL; 4121 return NULL;
4158 } 4122 }
4159 4123
4160 4124
4161 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4125 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4162 UNIMPLEMENTED(); 4126 UNIMPLEMENTED();
4163 } 4127 }
4164 4128
4165 4129
4166 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(Zone* zone, 4130 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(Zone* zone,
4167 bool opt) const { 4131 bool opt) const {
4168 UNIMPLEMENTED(); 4132 UNIMPLEMENTED();
4169 return NULL; 4133 return NULL;
4170 } 4134 }
4171 4135
4172 4136
4173 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4137 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4174 UNIMPLEMENTED(); 4138 UNIMPLEMENTED();
4175 } 4139 }
4176 4140
4177 4141
4178 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( 4142 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary(
4179 Zone* zone, bool opt) const { 4143 Zone* zone,
4144 bool opt) const {
4180 UNIMPLEMENTED(); 4145 UNIMPLEMENTED();
4181 return NULL; 4146 return NULL;
4182 } 4147 }
4183 4148
4184 4149
4185 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4150 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4186 UNIMPLEMENTED(); 4151 UNIMPLEMENTED();
4187 } 4152 }
4188 4153
4189 4154
4190 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( 4155 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary(
4191 Zone* zone, bool opt) const { 4156 Zone* zone,
4157 bool opt) const {
4192 UNIMPLEMENTED(); 4158 UNIMPLEMENTED();
4193 return NULL; 4159 return NULL;
4194 } 4160 }
4195 4161
4196 4162
4197 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4163 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4198 UNIMPLEMENTED(); 4164 UNIMPLEMENTED();
4199 } 4165 }
4200 4166
4201 4167
4202 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( 4168 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary(
4203 Zone* zone, bool opt) const { 4169 Zone* zone,
4170 bool opt) const {
4204 UNIMPLEMENTED(); 4171 UNIMPLEMENTED();
4205 return NULL; 4172 return NULL;
4206 } 4173 }
4207 4174
4208 4175
4209 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4176 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4210 UNIMPLEMENTED(); 4177 UNIMPLEMENTED();
4211 } 4178 }
4212 4179
4213 4180
(...skipping 14 matching lines...) Expand all
4228 UNIMPLEMENTED(); 4195 UNIMPLEMENTED();
4229 return NULL; 4196 return NULL;
4230 } 4197 }
4231 4198
4232 4199
4233 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4200 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4234 UNIMPLEMENTED(); 4201 UNIMPLEMENTED();
4235 } 4202 }
4236 4203
4237 4204
4238 LocationSummary* Int32x4ConstructorInstr::MakeLocationSummary( 4205 LocationSummary* Int32x4ConstructorInstr::MakeLocationSummary(Zone* zone,
4239 Zone* zone, bool opt) const { 4206 bool opt) const {
4240 UNIMPLEMENTED(); 4207 UNIMPLEMENTED();
4241 return NULL; 4208 return NULL;
4242 } 4209 }
4243 4210
4244 4211
4245 void Int32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4212 void Int32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4246 UNIMPLEMENTED(); 4213 UNIMPLEMENTED();
4247 } 4214 }
4248 4215
4249 4216
4250 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( 4217 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary(
4251 Zone* zone, bool opt) const { 4218 Zone* zone,
4219 bool opt) const {
4252 UNIMPLEMENTED(); 4220 UNIMPLEMENTED();
4253 return NULL; 4221 return NULL;
4254 } 4222 }
4255 4223
4256 4224
4257 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4225 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4258 UNIMPLEMENTED(); 4226 UNIMPLEMENTED();
4259 } 4227 }
4260 4228
4261 4229
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
4330 UNIMPLEMENTED(); 4298 UNIMPLEMENTED();
4331 } 4299 }
4332 4300
4333 4301
4334 LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone, 4302 LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
4335 bool opt) const { 4303 bool opt) const {
4336 ASSERT((kind() == MathUnaryInstr::kSqrt) || 4304 ASSERT((kind() == MathUnaryInstr::kSqrt) ||
4337 (kind() == MathUnaryInstr::kDoubleSquare)); 4305 (kind() == MathUnaryInstr::kDoubleSquare));
4338 const intptr_t kNumInputs = 1; 4306 const intptr_t kNumInputs = 1;
4339 const intptr_t kNumTemps = 0; 4307 const intptr_t kNumTemps = 0;
4340 LocationSummary* summary = new(zone) LocationSummary( 4308 LocationSummary* summary = new (zone)
4341 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4309 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4342 summary->set_in(0, Location::RequiresFpuRegister()); 4310 summary->set_in(0, Location::RequiresFpuRegister());
4343 summary->set_out(0, Location::RequiresFpuRegister()); 4311 summary->set_out(0, Location::RequiresFpuRegister());
4344 return summary; 4312 return summary;
4345 } 4313 }
4346 4314
4347 4315
4348 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4316 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4349 if (kind() == MathUnaryInstr::kSqrt) { 4317 if (kind() == MathUnaryInstr::kSqrt) {
4350 __ sqrtd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg()); 4318 __ sqrtd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4351 } else if (kind() == MathUnaryInstr::kDoubleSquare) { 4319 } else if (kind() == MathUnaryInstr::kDoubleSquare) {
4352 DRegister val = locs()->in(0).fpu_reg(); 4320 DRegister val = locs()->in(0).fpu_reg();
4353 DRegister result = locs()->out(0).fpu_reg(); 4321 DRegister result = locs()->out(0).fpu_reg();
4354 __ muld(result, val, val); 4322 __ muld(result, val, val);
4355 } else { 4323 } else {
4356 UNREACHABLE(); 4324 UNREACHABLE();
4357 } 4325 }
4358 } 4326 }
4359 4327
4360 4328
4361 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( 4329 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary(
4362 Zone* zone, bool opt) const { 4330 Zone* zone,
4331 bool opt) const {
4363 const intptr_t kNumTemps = 0; 4332 const intptr_t kNumTemps = 0;
4364 LocationSummary* summary = new(zone) LocationSummary( 4333 LocationSummary* summary = new (zone)
4365 zone, InputCount(), kNumTemps, LocationSummary::kCall); 4334 LocationSummary(zone, InputCount(), kNumTemps, LocationSummary::kCall);
4366 summary->set_in(0, Location::RegisterLocation(A0)); 4335 summary->set_in(0, Location::RegisterLocation(A0));
4367 summary->set_in(1, Location::RegisterLocation(A1)); 4336 summary->set_in(1, Location::RegisterLocation(A1));
4368 summary->set_in(2, Location::RegisterLocation(A2)); 4337 summary->set_in(2, Location::RegisterLocation(A2));
4369 summary->set_in(3, Location::RegisterLocation(A3)); 4338 summary->set_in(3, Location::RegisterLocation(A3));
4370 summary->set_out(0, Location::RegisterLocation(V0)); 4339 summary->set_out(0, Location::RegisterLocation(V0));
4371 return summary; 4340 return summary;
4372 } 4341 }
4373 4342
4374 4343
4375 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( 4344 void CaseInsensitiveCompareUC16Instr::EmitNativeCode(
4376 FlowGraphCompiler* compiler) { 4345 FlowGraphCompiler* compiler) {
4377
4378 // Call the function. 4346 // Call the function.
4379 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); 4347 __ CallRuntime(TargetFunction(), TargetFunction().argument_count());
4380 } 4348 }
4381 4349
4382 4350
4383 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Zone* zone, 4351 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Zone* zone,
4384 bool opt) const { 4352 bool opt) const {
4385 if (result_cid() == kDoubleCid) { 4353 if (result_cid() == kDoubleCid) {
4386 const intptr_t kNumInputs = 2; 4354 const intptr_t kNumInputs = 2;
4387 const intptr_t kNumTemps = 1; 4355 const intptr_t kNumTemps = 1;
4388 LocationSummary* summary = new(zone) LocationSummary( 4356 LocationSummary* summary = new (zone)
4389 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4357 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4390 summary->set_in(0, Location::RequiresFpuRegister()); 4358 summary->set_in(0, Location::RequiresFpuRegister());
4391 summary->set_in(1, Location::RequiresFpuRegister()); 4359 summary->set_in(1, Location::RequiresFpuRegister());
4392 // Reuse the left register so that code can be made shorter. 4360 // Reuse the left register so that code can be made shorter.
4393 summary->set_out(0, Location::SameAsFirstInput()); 4361 summary->set_out(0, Location::SameAsFirstInput());
4394 summary->set_temp(0, Location::RequiresRegister()); 4362 summary->set_temp(0, Location::RequiresRegister());
4395 return summary; 4363 return summary;
4396 } 4364 }
4397 ASSERT(result_cid() == kSmiCid); 4365 ASSERT(result_cid() == kSmiCid);
4398 const intptr_t kNumInputs = 2; 4366 const intptr_t kNumInputs = 2;
4399 const intptr_t kNumTemps = 0; 4367 const intptr_t kNumTemps = 0;
4400 LocationSummary* summary = new(zone) LocationSummary( 4368 LocationSummary* summary = new (zone)
4401 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4369 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4402 summary->set_in(0, Location::RequiresRegister()); 4370 summary->set_in(0, Location::RequiresRegister());
4403 summary->set_in(1, Location::RequiresRegister()); 4371 summary->set_in(1, Location::RequiresRegister());
4404 // Reuse the left register so that code can be made shorter. 4372 // Reuse the left register so that code can be made shorter.
4405 summary->set_out(0, Location::SameAsFirstInput()); 4373 summary->set_out(0, Location::SameAsFirstInput());
4406 return summary; 4374 return summary;
4407 } 4375 }
4408 4376
4409 4377
4410 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4378 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4411 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 4379 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4469 } 4437 }
4470 __ mov(result, right); 4438 __ mov(result, right);
4471 __ Bind(&done); 4439 __ Bind(&done);
4472 } 4440 }
4473 4441
4474 4442
4475 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Zone* zone, 4443 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Zone* zone,
4476 bool opt) const { 4444 bool opt) const {
4477 const intptr_t kNumInputs = 1; 4445 const intptr_t kNumInputs = 1;
4478 const intptr_t kNumTemps = 0; 4446 const intptr_t kNumTemps = 0;
4479 LocationSummary* summary = new(zone) LocationSummary( 4447 LocationSummary* summary = new (zone)
4480 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4448 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4481 summary->set_in(0, Location::RequiresRegister()); 4449 summary->set_in(0, Location::RequiresRegister());
4482 // We make use of 3-operand instructions by not requiring result register 4450 // We make use of 3-operand instructions by not requiring result register
4483 // to be identical to first input register as on Intel. 4451 // to be identical to first input register as on Intel.
4484 summary->set_out(0, Location::RequiresRegister()); 4452 summary->set_out(0, Location::RequiresRegister());
4485 return summary; 4453 return summary;
4486 } 4454 }
4487 4455
4488 4456
4489 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4457 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4490 Register value = locs()->in(0).reg(); 4458 Register value = locs()->in(0).reg();
(...skipping 12 matching lines...) Expand all
4503 default: 4471 default:
4504 UNREACHABLE(); 4472 UNREACHABLE();
4505 } 4473 }
4506 } 4474 }
4507 4475
4508 4476
4509 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone, 4477 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
4510 bool opt) const { 4478 bool opt) const {
4511 const intptr_t kNumInputs = 1; 4479 const intptr_t kNumInputs = 1;
4512 const intptr_t kNumTemps = 0; 4480 const intptr_t kNumTemps = 0;
4513 LocationSummary* summary = new(zone) LocationSummary( 4481 LocationSummary* summary = new (zone)
4514 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4482 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4515 summary->set_in(0, Location::RequiresFpuRegister()); 4483 summary->set_in(0, Location::RequiresFpuRegister());
4516 summary->set_out(0, Location::RequiresFpuRegister()); 4484 summary->set_out(0, Location::RequiresFpuRegister());
4517 return summary; 4485 return summary;
4518 } 4486 }
4519 4487
4520 4488
4521 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4489 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4522 FpuRegister result = locs()->out(0).fpu_reg(); 4490 FpuRegister result = locs()->out(0).fpu_reg();
4523 FpuRegister value = locs()->in(0).fpu_reg(); 4491 FpuRegister value = locs()->in(0).fpu_reg();
4524 __ negd(result, value); 4492 __ negd(result, value);
4525 } 4493 }
4526 4494
4527 4495
4528 LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone, 4496 LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone,
4529 bool opt) const { 4497 bool opt) const {
4530 const intptr_t kNumInputs = 1; 4498 const intptr_t kNumInputs = 1;
4531 const intptr_t kNumTemps = 0; 4499 const intptr_t kNumTemps = 0;
4532 LocationSummary* result = new(zone) LocationSummary( 4500 LocationSummary* result = new (zone)
4533 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4501 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4534 result->set_in(0, Location::RequiresRegister()); 4502 result->set_in(0, Location::RequiresRegister());
4535 result->set_out(0, Location::RequiresFpuRegister()); 4503 result->set_out(0, Location::RequiresFpuRegister());
4536 return result; 4504 return result;
4537 } 4505 }
4538 4506
4539 4507
4540 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4508 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4541 Register value = locs()->in(0).reg(); 4509 Register value = locs()->in(0).reg();
4542 FpuRegister result = locs()->out(0).fpu_reg(); 4510 FpuRegister result = locs()->out(0).fpu_reg();
4543 __ mtc1(value, STMP1); 4511 __ mtc1(value, STMP1);
4544 __ cvtdw(result, STMP1); 4512 __ cvtdw(result, STMP1);
4545 } 4513 }
4546 4514
4547 4515
4548 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Zone* zone, 4516 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Zone* zone,
4549 bool opt) const { 4517 bool opt) const {
4550 const intptr_t kNumInputs = 1; 4518 const intptr_t kNumInputs = 1;
4551 const intptr_t kNumTemps = 0; 4519 const intptr_t kNumTemps = 0;
4552 LocationSummary* result = new(zone) LocationSummary( 4520 LocationSummary* result = new (zone)
4553 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4521 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4554 result->set_in(0, Location::RequiresRegister()); 4522 result->set_in(0, Location::RequiresRegister());
4555 result->set_out(0, Location::RequiresFpuRegister()); 4523 result->set_out(0, Location::RequiresFpuRegister());
4556 return result; 4524 return result;
4557 } 4525 }
4558 4526
4559 4527
4560 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4528 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4561 Register value = locs()->in(0).reg(); 4529 Register value = locs()->in(0).reg();
4562 FpuRegister result = locs()->out(0).fpu_reg(); 4530 FpuRegister result = locs()->out(0).fpu_reg();
4563 __ SmiUntag(TMP, value); 4531 __ SmiUntag(TMP, value);
(...skipping 11 matching lines...) Expand all
4575 4543
4576 void MintToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4544 void MintToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4577 UNIMPLEMENTED(); 4545 UNIMPLEMENTED();
4578 } 4546 }
4579 4547
4580 4548
4581 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Zone* zone, 4549 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Zone* zone,
4582 bool opt) const { 4550 bool opt) const {
4583 const intptr_t kNumInputs = 1; 4551 const intptr_t kNumInputs = 1;
4584 const intptr_t kNumTemps = 0; 4552 const intptr_t kNumTemps = 0;
4585 LocationSummary* result = new(zone) LocationSummary( 4553 LocationSummary* result = new (zone)
4586 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 4554 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
4587 result->set_in(0, Location::RegisterLocation(T1)); 4555 result->set_in(0, Location::RegisterLocation(T1));
4588 result->set_out(0, Location::RegisterLocation(V0)); 4556 result->set_out(0, Location::RegisterLocation(V0));
4589 return result; 4557 return result;
4590 } 4558 }
4591 4559
4592 4560
4593 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4561 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4594 Register result = locs()->out(0).reg(); 4562 Register result = locs()->out(0).reg();
4595 Register value_obj = locs()->in(0).reg(); 4563 Register value_obj = locs()->in(0).reg();
4596 ASSERT(result == V0); 4564 ASSERT(result == V0);
(...skipping 11 matching lines...) Expand all
4608 __ SmiTag(result); 4576 __ SmiTag(result);
4609 __ b(&done); 4577 __ b(&done);
4610 __ Bind(&do_call); 4578 __ Bind(&do_call);
4611 __ Push(value_obj); 4579 __ Push(value_obj);
4612 ASSERT(instance_call()->HasICData()); 4580 ASSERT(instance_call()->HasICData());
4613 const ICData& ic_data = *instance_call()->ic_data(); 4581 const ICData& ic_data = *instance_call()->ic_data();
4614 ASSERT((ic_data.NumberOfChecks() == 1)); 4582 ASSERT((ic_data.NumberOfChecks() == 1));
4615 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 4583 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
4616 4584
4617 const intptr_t kNumberOfArguments = 1; 4585 const intptr_t kNumberOfArguments = 1;
4618 compiler->GenerateStaticCall(deopt_id(), 4586 compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target,
4619 instance_call()->token_pos(),
4620 target,
4621 kNumberOfArguments, 4587 kNumberOfArguments,
4622 Object::null_array(), // No argument names. 4588 Object::null_array(), // No argument names.
4623 locs(), 4589 locs(), ICData::Handle());
4624 ICData::Handle());
4625 __ Bind(&done); 4590 __ Bind(&done);
4626 } 4591 }
4627 4592
4628 4593
4629 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(Zone* zone, 4594 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(Zone* zone,
4630 bool opt) const { 4595 bool opt) const {
4631 const intptr_t kNumInputs = 1; 4596 const intptr_t kNumInputs = 1;
4632 const intptr_t kNumTemps = 0; 4597 const intptr_t kNumTemps = 0;
4633 LocationSummary* result = new(zone) LocationSummary( 4598 LocationSummary* result = new (zone)
4634 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4599 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4635 result->set_in(0, Location::RequiresFpuRegister()); 4600 result->set_in(0, Location::RequiresFpuRegister());
4636 result->set_out(0, Location::RequiresRegister()); 4601 result->set_out(0, Location::RequiresRegister());
4637 return result; 4602 return result;
4638 } 4603 }
4639 4604
4640 4605
4641 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4606 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4642 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi); 4607 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi);
4643 Register result = locs()->out(0).reg(); 4608 Register result = locs()->out(0).reg();
4644 DRegister value = locs()->in(0).fpu_reg(); 4609 DRegister value = locs()->in(0).fpu_reg();
(...skipping 17 matching lines...) Expand all
4662 4627
4663 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4628 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4664 UNIMPLEMENTED(); 4629 UNIMPLEMENTED();
4665 } 4630 }
4666 4631
4667 4632
4668 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone, 4633 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
4669 bool opt) const { 4634 bool opt) const {
4670 const intptr_t kNumInputs = 1; 4635 const intptr_t kNumInputs = 1;
4671 const intptr_t kNumTemps = 0; 4636 const intptr_t kNumTemps = 0;
4672 LocationSummary* result = new(zone) LocationSummary( 4637 LocationSummary* result = new (zone)
4673 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4638 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4674 result->set_in(0, Location::RequiresFpuRegister()); 4639 result->set_in(0, Location::RequiresFpuRegister());
4675 result->set_out(0, Location::SameAsFirstInput()); 4640 result->set_out(0, Location::SameAsFirstInput());
4676 return result; 4641 return result;
4677 } 4642 }
4678 4643
4679 4644
4680 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4645 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4681 DRegister value = locs()->in(0).fpu_reg(); 4646 DRegister value = locs()->in(0).fpu_reg();
4682 FRegister result = EvenFRegisterOf(locs()->out(0).fpu_reg()); 4647 FRegister result = EvenFRegisterOf(locs()->out(0).fpu_reg());
4683 __ cvtsd(result, value); 4648 __ cvtsd(result, value);
4684 } 4649 }
4685 4650
4686 4651
4687 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(Zone* zone, 4652 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(Zone* zone,
4688 bool opt) const { 4653 bool opt) const {
4689 const intptr_t kNumInputs = 1; 4654 const intptr_t kNumInputs = 1;
4690 const intptr_t kNumTemps = 0; 4655 const intptr_t kNumTemps = 0;
4691 LocationSummary* result = new(zone) LocationSummary( 4656 LocationSummary* result = new (zone)
4692 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4657 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4693 result->set_in(0, Location::RequiresFpuRegister()); 4658 result->set_in(0, Location::RequiresFpuRegister());
4694 result->set_out(0, Location::SameAsFirstInput()); 4659 result->set_out(0, Location::SameAsFirstInput());
4695 return result; 4660 return result;
4696 } 4661 }
4697 4662
4698 4663
4699 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4664 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4700 FRegister value = EvenFRegisterOf(locs()->in(0).fpu_reg()); 4665 FRegister value = EvenFRegisterOf(locs()->in(0).fpu_reg());
4701 DRegister result = locs()->out(0).fpu_reg(); 4666 DRegister result = locs()->out(0).fpu_reg();
4702 __ cvtds(result, value); 4667 __ cvtds(result, value);
4703 } 4668 }
4704 4669
4705 4670
4706 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone, 4671 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
4707 bool opt) const { 4672 bool opt) const {
4708 // Calling convention on MIPS uses D6 and D7 to pass the first two 4673 // Calling convention on MIPS uses D6 and D7 to pass the first two
4709 // double arguments. 4674 // double arguments.
4710 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4675 ASSERT((InputCount() == 1) || (InputCount() == 2));
4711 const intptr_t kNumTemps = 0; 4676 const intptr_t kNumTemps = 0;
4712 LocationSummary* result = new(zone) LocationSummary( 4677 LocationSummary* result = new (zone)
4713 zone, InputCount(), kNumTemps, LocationSummary::kCall); 4678 LocationSummary(zone, InputCount(), kNumTemps, LocationSummary::kCall);
4714 result->set_in(0, Location::FpuRegisterLocation(D6)); 4679 result->set_in(0, Location::FpuRegisterLocation(D6));
4715 if (InputCount() == 2) { 4680 if (InputCount() == 2) {
4716 result->set_in(1, Location::FpuRegisterLocation(D7)); 4681 result->set_in(1, Location::FpuRegisterLocation(D7));
4717 } 4682 }
4718 result->set_out(0, Location::FpuRegisterLocation(D0)); 4683 result->set_out(0, Location::FpuRegisterLocation(D0));
4719 return result; 4684 return result;
4720 } 4685 }
4721 4686
4722 4687
4723 // Pseudo code: 4688 // Pseudo code:
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4842 // double values are passed and returned in vfp registers. 4807 // double values are passed and returned in vfp registers.
4843 __ CallRuntime(TargetFunction(), InputCount()); 4808 __ CallRuntime(TargetFunction(), InputCount());
4844 } 4809 }
4845 4810
4846 4811
4847 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(Zone* zone, 4812 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(Zone* zone,
4848 bool opt) const { 4813 bool opt) const {
4849 // Only use this instruction in optimized code. 4814 // Only use this instruction in optimized code.
4850 ASSERT(opt); 4815 ASSERT(opt);
4851 const intptr_t kNumInputs = 1; 4816 const intptr_t kNumInputs = 1;
4852 LocationSummary* summary = new(zone) LocationSummary( 4817 LocationSummary* summary =
4853 zone, kNumInputs, 0, LocationSummary::kNoCall); 4818 new (zone) LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall);
4854 if (representation() == kUnboxedDouble) { 4819 if (representation() == kUnboxedDouble) {
4855 if (index() == 0) { 4820 if (index() == 0) {
4856 summary->set_in(0, Location::Pair(Location::RequiresFpuRegister(), 4821 summary->set_in(
4857 Location::Any())); 4822 0, Location::Pair(Location::RequiresFpuRegister(), Location::Any()));
4858 } else { 4823 } else {
4859 ASSERT(index() == 1); 4824 ASSERT(index() == 1);
4860 summary->set_in(0, Location::Pair(Location::Any(), 4825 summary->set_in(
4861 Location::RequiresFpuRegister())); 4826 0, Location::Pair(Location::Any(), Location::RequiresFpuRegister()));
4862 } 4827 }
4863 summary->set_out(0, Location::RequiresFpuRegister()); 4828 summary->set_out(0, Location::RequiresFpuRegister());
4864 } else { 4829 } else {
4865 ASSERT(representation() == kTagged); 4830 ASSERT(representation() == kTagged);
4866 if (index() == 0) { 4831 if (index() == 0) {
4867 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 4832 summary->set_in(
4868 Location::Any())); 4833 0, Location::Pair(Location::RequiresRegister(), Location::Any()));
4869 } else { 4834 } else {
4870 ASSERT(index() == 1); 4835 ASSERT(index() == 1);
4871 summary->set_in(0, Location::Pair(Location::Any(), 4836 summary->set_in(
4872 Location::RequiresRegister())); 4837 0, Location::Pair(Location::Any(), Location::RequiresRegister()));
4873 } 4838 }
4874 summary->set_out(0, Location::RequiresRegister()); 4839 summary->set_out(0, Location::RequiresRegister());
4875 } 4840 }
4876 return summary; 4841 return summary;
4877 } 4842 }
4878 4843
4879 4844
4880 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4845 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4881 ASSERT(locs()->in(0).IsPairLocation()); 4846 ASSERT(locs()->in(0).IsPairLocation());
4882 PairLocation* pair = locs()->in(0).AsPairLocation(); 4847 PairLocation* pair = locs()->in(0).AsPairLocation();
4883 Location in_loc = pair->At(index()); 4848 Location in_loc = pair->At(index());
4884 if (representation() == kUnboxedDouble) { 4849 if (representation() == kUnboxedDouble) {
4885 DRegister out = locs()->out(0).fpu_reg(); 4850 DRegister out = locs()->out(0).fpu_reg();
4886 DRegister in = in_loc.fpu_reg(); 4851 DRegister in = in_loc.fpu_reg();
4887 __ movd(out, in); 4852 __ movd(out, in);
4888 } else { 4853 } else {
4889 ASSERT(representation() == kTagged); 4854 ASSERT(representation() == kTagged);
4890 Register out = locs()->out(0).reg(); 4855 Register out = locs()->out(0).reg();
4891 Register in = in_loc.reg(); 4856 Register in = in_loc.reg();
4892 __ mov(out, in); 4857 __ mov(out, in);
4893 } 4858 }
4894 } 4859 }
4895 4860
4896 4861
4897 LocationSummary* MergedMathInstr::MakeLocationSummary(Zone* zone, 4862 LocationSummary* MergedMathInstr::MakeLocationSummary(Zone* zone,
4898 bool opt) const { 4863 bool opt) const {
4899 if (kind() == MergedMathInstr::kTruncDivMod) { 4864 if (kind() == MergedMathInstr::kTruncDivMod) {
4900 const intptr_t kNumInputs = 2; 4865 const intptr_t kNumInputs = 2;
4901 const intptr_t kNumTemps = 1; 4866 const intptr_t kNumTemps = 1;
4902 LocationSummary* summary = new(zone) LocationSummary( 4867 LocationSummary* summary = new (zone)
4903 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4868 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4904 summary->set_in(0, Location::RequiresRegister()); 4869 summary->set_in(0, Location::RequiresRegister());
4905 summary->set_in(1, Location::RequiresRegister()); 4870 summary->set_in(1, Location::RequiresRegister());
4906 summary->set_temp(0, Location::RequiresRegister()); 4871 summary->set_temp(0, Location::RequiresRegister());
4907 // Output is a pair of registers. 4872 // Output is a pair of registers.
4908 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 4873 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
4909 Location::RequiresRegister())); 4874 Location::RequiresRegister()));
4910 return summary; 4875 return summary;
4911 } 4876 }
4912 UNIMPLEMENTED(); 4877 UNIMPLEMENTED();
4913 return NULL; 4878 return NULL;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4968 4933
4969 __ SmiTag(result_div); 4934 __ SmiTag(result_div);
4970 __ SmiTag(result_mod); 4935 __ SmiTag(result_mod);
4971 return; 4936 return;
4972 } 4937 }
4973 UNIMPLEMENTED(); 4938 UNIMPLEMENTED();
4974 } 4939 }
4975 4940
4976 4941
4977 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 4942 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
4978 Zone* zone, bool opt) const { 4943 Zone* zone,
4944 bool opt) const {
4979 return MakeCallSummary(zone); 4945 return MakeCallSummary(zone);
4980 } 4946 }
4981 4947
4982 4948
4983 LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, 4949 LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
4984 bool opt) const {
4985 comparison()->InitializeLocationSummary(zone, opt); 4950 comparison()->InitializeLocationSummary(zone, opt);
4986 // Branches don't produce a result. 4951 // Branches don't produce a result.
4987 comparison()->locs()->set_out(0, Location::NoLocation()); 4952 comparison()->locs()->set_out(0, Location::NoLocation());
4988 return comparison()->locs(); 4953 return comparison()->locs();
4989 } 4954 }
4990 4955
4991 4956
4992 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4957 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4993 __ Comment("BranchInstr"); 4958 __ Comment("BranchInstr");
4994 comparison()->EmitBranchCode(compiler, this); 4959 comparison()->EmitBranchCode(compiler, this);
4995 } 4960 }
4996 4961
4997 4962
4998 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 4963 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
4999 bool opt) const { 4964 bool opt) const {
5000 const intptr_t kNumInputs = 1; 4965 const intptr_t kNumInputs = 1;
5001 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); 4966 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask());
5002 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 4967 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
5003 LocationSummary* summary = new(zone) LocationSummary( 4968 LocationSummary* summary = new (zone)
5004 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4969 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5005 summary->set_in(0, Location::RequiresRegister()); 4970 summary->set_in(0, Location::RequiresRegister());
5006 if (!IsNullCheck()) { 4971 if (!IsNullCheck()) {
5007 summary->set_temp(0, Location::RequiresRegister()); 4972 summary->set_temp(0, Location::RequiresRegister());
5008 if (need_mask_temp) { 4973 if (need_mask_temp) {
5009 summary->set_temp(1, Location::RequiresRegister()); 4974 summary->set_temp(1, Location::RequiresRegister());
5010 } 4975 }
5011 } 4976 }
5012 return summary; 4977 return summary;
5013 } 4978 }
5014 4979
5015 4980
5016 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4981 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5017 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4982 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass,
5018 ICData::kDeoptCheckClass,
5019 licm_hoisted_ ? ICData::kHoisted : 0); 4983 licm_hoisted_ ? ICData::kHoisted : 0);
5020 if (IsNullCheck()) { 4984 if (IsNullCheck()) {
5021 if (DeoptIfNull()) { 4985 if (DeoptIfNull()) {
5022 __ BranchEqual(locs()->in(0).reg(), Object::null_object(), deopt); 4986 __ BranchEqual(locs()->in(0).reg(), Object::null_object(), deopt);
5023 } else { 4987 } else {
5024 ASSERT(DeoptIfNotNull()); 4988 ASSERT(DeoptIfNotNull());
5025 __ BranchNotEqual(locs()->in(0).reg(), Object::null_object(), deopt); 4989 __ BranchNotEqual(locs()->in(0).reg(), Object::null_object(), deopt);
5026 } 4990 }
5027 return; 4991 return;
5028 } 4992 }
(...skipping 24 matching lines...) Expand all
5053 // Only need mask if there are missing numbers in the range. 5017 // Only need mask if there are missing numbers in the range.
5054 ASSERT(cids_.length() > 2); 5018 ASSERT(cids_.length() > 2);
5055 Register mask_reg = locs()->temp(1).reg(); 5019 Register mask_reg = locs()->temp(1).reg();
5056 __ LoadImmediate(mask_reg, 1); 5020 __ LoadImmediate(mask_reg, 1);
5057 __ sllv(mask_reg, mask_reg, temp); 5021 __ sllv(mask_reg, mask_reg, temp);
5058 __ AndImmediate(mask_reg, mask_reg, mask); 5022 __ AndImmediate(mask_reg, mask_reg, mask);
5059 __ beq(mask_reg, ZR, deopt); 5023 __ beq(mask_reg, ZR, deopt);
5060 } 5024 }
5061 } else { 5025 } else {
5062 GrowableArray<CidTarget> sorted_ic_data; 5026 GrowableArray<CidTarget> sorted_ic_data;
5063 FlowGraphCompiler::SortICDataByCount(unary_checks(), 5027 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data,
5064 &sorted_ic_data,
5065 /* drop_smi = */ true); 5028 /* drop_smi = */ true);
5066 const intptr_t num_checks = sorted_ic_data.length(); 5029 const intptr_t num_checks = sorted_ic_data.length();
5067 for (intptr_t i = 0; i < num_checks; i++) { 5030 for (intptr_t i = 0; i < num_checks; i++) {
5068 const intptr_t cid = sorted_ic_data[i].cid; 5031 const intptr_t cid = sorted_ic_data[i].cid;
5069 ASSERT(cid != kSmiCid); 5032 ASSERT(cid != kSmiCid);
5070 __ LoadImmediate(TMP, cid); 5033 __ LoadImmediate(TMP, cid);
5071 __ subu(CMPRES1, temp, TMP); 5034 __ subu(CMPRES1, temp, TMP);
5072 if (i == (num_checks - 1)) { 5035 if (i == (num_checks - 1)) {
5073 __ bne(CMPRES1, ZR, deopt); 5036 __ bne(CMPRES1, ZR, deopt);
5074 } else { 5037 } else {
5075 __ beq(CMPRES1, ZR, &is_ok); 5038 __ beq(CMPRES1, ZR, &is_ok);
5076 } 5039 }
5077 } 5040 }
5078 } 5041 }
5079 __ Bind(&is_ok); 5042 __ Bind(&is_ok);
5080 } 5043 }
5081 5044
5082 5045
5083 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, 5046 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone,
5084 bool opt) const { 5047 bool opt) const {
5085 const intptr_t kNumInputs = 1; 5048 const intptr_t kNumInputs = 1;
5086 const intptr_t kNumTemps = 0; 5049 const intptr_t kNumTemps = 0;
5087 LocationSummary* summary = new(zone) LocationSummary( 5050 LocationSummary* summary = new (zone)
5088 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5051 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5089 summary->set_in(0, Location::RequiresRegister()); 5052 summary->set_in(0, Location::RequiresRegister());
5090 return summary; 5053 return summary;
5091 } 5054 }
5092 5055
5093 5056
5094 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5057 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5095 __ Comment("CheckSmiInstr"); 5058 __ Comment("CheckSmiInstr");
5096 Register value = locs()->in(0).reg(); 5059 Register value = locs()->in(0).reg();
5097 Label* deopt = compiler->AddDeoptStub(deopt_id(), 5060 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi,
5098 ICData::kDeoptCheckSmi,
5099 licm_hoisted_ ? ICData::kHoisted : 0); 5061 licm_hoisted_ ? ICData::kHoisted : 0);
5100 __ BranchIfNotSmi(value, deopt); 5062 __ BranchIfNotSmi(value, deopt);
5101 } 5063 }
5102 5064
5103 5065
5104 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, 5066 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
5105 bool opt) const { 5067 bool opt) const {
5106 const intptr_t kNumInputs = 1; 5068 const intptr_t kNumInputs = 1;
5107 const intptr_t kNumTemps = 0; 5069 const intptr_t kNumTemps = 0;
5108 LocationSummary* summary = new(zone) LocationSummary( 5070 LocationSummary* summary = new (zone)
5109 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5071 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5110 summary->set_in(0, Location::RequiresRegister()); 5072 summary->set_in(0, Location::RequiresRegister());
5111 return summary; 5073 return summary;
5112 } 5074 }
5113 5075
5114 5076
5115 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5077 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5116 Register value = locs()->in(0).reg(); 5078 Register value = locs()->in(0).reg();
5117 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); 5079 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass);
5118 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); 5080 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt);
5119 } 5081 }
5120 5082
5121 5083
5122 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone, 5084 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
5123 bool opt) const { 5085 bool opt) const {
5124 const intptr_t kNumInputs = 2; 5086 const intptr_t kNumInputs = 2;
5125 const intptr_t kNumTemps = 0; 5087 const intptr_t kNumTemps = 0;
5126 LocationSummary* locs = new(zone) LocationSummary( 5088 LocationSummary* locs = new (zone) LocationSummary(
5127 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 5089 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
5128 locs->set_in(kLengthPos, Location::RequiresRegister()); 5090 locs->set_in(kLengthPos, Location::RequiresRegister());
5129 locs->set_in(kIndexPos, Location::RequiresRegister()); 5091 locs->set_in(kIndexPos, Location::RequiresRegister());
5130 return locs; 5092 return locs;
5131 } 5093 }
5132 5094
5133 5095
5134 class RangeErrorSlowPath : public SlowPathCode { 5096 class RangeErrorSlowPath : public SlowPathCode {
5135 public: 5097 public:
5136 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) 5098 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
5137 : instruction_(instruction), try_index_(try_index) { } 5099 : instruction_(instruction), try_index_(try_index) {}
5138 5100
5139 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5101 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5140 if (Assembler::EmittingComments()) { 5102 if (Assembler::EmittingComments()) {
5141 __ Comment("slow path check bound operation"); 5103 __ Comment("slow path check bound operation");
5142 } 5104 }
5143 __ Bind(entry_label()); 5105 __ Bind(entry_label());
5144 LocationSummary* locs = instruction_->locs(); 5106 LocationSummary* locs = instruction_->locs();
5145 __ Push(locs->in(0).reg()); 5107 __ Push(locs->in(0).reg());
5146 __ Push(locs->in(1).reg()); 5108 __ Push(locs->in(1).reg());
5147 __ CallRuntime(kRangeErrorRuntimeEntry, 2); 5109 __ CallRuntime(kRangeErrorRuntimeEntry, 2);
5148 compiler->pc_descriptors_list()->AddDescriptor( 5110 compiler->pc_descriptors_list()->AddDescriptor(
5149 RawPcDescriptors::kOther, 5111 RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
5150 compiler->assembler()->CodeSize(), 5112 instruction_->deopt_id(), instruction_->token_pos(), try_index_);
5151 instruction_->deopt_id(),
5152 instruction_->token_pos(),
5153 try_index_);
5154 __ break_(0); 5113 __ break_(0);
5155 } 5114 }
5156 5115
5157 private: 5116 private:
5158 GenericCheckBoundInstr* instruction_; 5117 GenericCheckBoundInstr* instruction_;
5159 intptr_t try_index_; 5118 intptr_t try_index_;
5160 }; 5119 };
5161 5120
5162 5121
5163 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5122 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 10 matching lines...) Expand all
5174 __ BranchIfNotSmi(index, slow_path->entry_label()); 5133 __ BranchIfNotSmi(index, slow_path->entry_label());
5175 } 5134 }
5176 __ BranchUnsignedGreaterEqual(index, length, slow_path->entry_label()); 5135 __ BranchUnsignedGreaterEqual(index, length, slow_path->entry_label());
5177 } 5136 }
5178 5137
5179 5138
5180 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, 5139 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
5181 bool opt) const { 5140 bool opt) const {
5182 const intptr_t kNumInputs = 2; 5141 const intptr_t kNumInputs = 2;
5183 const intptr_t kNumTemps = 0; 5142 const intptr_t kNumTemps = 0;
5184 LocationSummary* locs = new(zone) LocationSummary( 5143 LocationSummary* locs = new (zone)
5185 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5144 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5186 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); 5145 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
5187 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); 5146 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
5188 return locs; 5147 return locs;
5189 } 5148 }
5190 5149
5191 5150
5192 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5151 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5193 uint32_t flags = generalized_ ? ICData::kGeneralized : 0; 5152 uint32_t flags = generalized_ ? ICData::kGeneralized : 0;
5194 flags |= licm_hoisted_ ? ICData::kHoisted : 0; 5153 flags |= licm_hoisted_ ? ICData::kHoisted : 0;
5195 Label* deopt = compiler->AddDeoptStub( 5154 Label* deopt =
5196 deopt_id(), 5155 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckArrayBound, flags);
5197 ICData::kDeoptCheckArrayBound,
5198 flags);
5199 5156
5200 Location length_loc = locs()->in(kLengthPos); 5157 Location length_loc = locs()->in(kLengthPos);
5201 Location index_loc = locs()->in(kIndexPos); 5158 Location index_loc = locs()->in(kIndexPos);
5202 5159
5203 if (length_loc.IsConstant() && index_loc.IsConstant()) { 5160 if (length_loc.IsConstant() && index_loc.IsConstant()) {
5204 ASSERT((Smi::Cast(length_loc.constant()).Value() <= 5161 ASSERT((Smi::Cast(length_loc.constant()).Value() <=
5205 Smi::Cast(index_loc.constant()).Value()) || 5162 Smi::Cast(index_loc.constant()).Value()) ||
5206 (Smi::Cast(index_loc.constant()).Value() < 0)); 5163 (Smi::Cast(index_loc.constant()).Value() < 0));
5207 // Unconditionally deoptimize for constant bounds checks because they 5164 // Unconditionally deoptimize for constant bounds checks because they
5208 // only occur only when index is out-of-bounds. 5165 // only occur only when index is out-of-bounds.
(...skipping 26 matching lines...) Expand all
5235 __ BranchIfNotSmi(index, deopt); 5192 __ BranchIfNotSmi(index, deopt);
5236 } 5193 }
5237 __ BranchUnsignedGreaterEqual(index, length, deopt); 5194 __ BranchUnsignedGreaterEqual(index, length, deopt);
5238 } 5195 }
5239 } 5196 }
5240 5197
5241 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, 5198 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone,
5242 bool opt) const { 5199 bool opt) const {
5243 const intptr_t kNumInputs = 2; 5200 const intptr_t kNumInputs = 2;
5244 const intptr_t kNumTemps = 0; 5201 const intptr_t kNumTemps = 0;
5245 LocationSummary* summary = new(zone) LocationSummary( 5202 LocationSummary* summary = new (zone)
5246 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5203 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5247 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5204 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5248 Location::RequiresRegister())); 5205 Location::RequiresRegister()));
5249 summary->set_in(1, Location::Pair(Location::RequiresRegister(), 5206 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5250 Location::RequiresRegister())); 5207 Location::RequiresRegister()));
5251 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 5208 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5252 Location::RequiresRegister())); 5209 Location::RequiresRegister()));
5253 return summary; 5210 return summary;
5254 } 5211 }
5255 5212
5256 5213
(...skipping 17 matching lines...) Expand all
5274 __ and_(out_lo, left_lo, right_lo); 5231 __ and_(out_lo, left_lo, right_lo);
5275 __ and_(out_hi, left_hi, right_hi); 5232 __ and_(out_hi, left_hi, right_hi);
5276 break; 5233 break;
5277 } 5234 }
5278 case Token::kBIT_OR: { 5235 case Token::kBIT_OR: {
5279 __ or_(out_lo, left_lo, right_lo); 5236 __ or_(out_lo, left_lo, right_lo);
5280 __ or_(out_hi, left_hi, right_hi); 5237 __ or_(out_hi, left_hi, right_hi);
5281 break; 5238 break;
5282 } 5239 }
5283 case Token::kBIT_XOR: { 5240 case Token::kBIT_XOR: {
5284 __ xor_(out_lo, left_lo, right_lo); 5241 __ xor_(out_lo, left_lo, right_lo);
5285 __ xor_(out_hi, left_hi, right_hi); 5242 __ xor_(out_hi, left_hi, right_hi);
5286 break; 5243 break;
5287 } 5244 }
5288 case Token::kADD: 5245 case Token::kADD:
5289 case Token::kSUB: { 5246 case Token::kSUB: {
5290 if (op_kind() == Token::kADD) { 5247 if (op_kind() == Token::kADD) {
5291 __ addu(out_lo, left_lo, right_lo); 5248 __ addu(out_lo, left_lo, right_lo);
5292 __ sltu(TMP, out_lo, left_lo); // TMP = carry of left_lo + right_lo. 5249 __ sltu(TMP, out_lo, left_lo); // TMP = carry of left_lo + right_lo.
5293 __ addu(out_hi, left_hi, right_hi); 5250 __ addu(out_hi, left_hi, right_hi);
5294 __ addu(out_hi, out_hi, TMP); 5251 __ addu(out_hi, out_hi, TMP);
5295 if (can_overflow()) { 5252 if (can_overflow()) {
5296 __ xor_(CMPRES1, out_hi, left_hi); 5253 __ xor_(CMPRES1, out_hi, left_hi);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5329 default: 5286 default:
5330 UNREACHABLE(); 5287 UNREACHABLE();
5331 } 5288 }
5332 } 5289 }
5333 5290
5334 5291
5335 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, 5292 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone,
5336 bool opt) const { 5293 bool opt) const {
5337 const intptr_t kNumInputs = 2; 5294 const intptr_t kNumInputs = 2;
5338 const intptr_t kNumTemps = 0; 5295 const intptr_t kNumTemps = 0;
5339 LocationSummary* summary = new(zone) LocationSummary( 5296 LocationSummary* summary = new (zone)
5340 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5297 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5341 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5298 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5342 Location::RequiresRegister())); 5299 Location::RequiresRegister()));
5343 summary->set_in(1, Location::WritableRegisterOrSmiConstant(right())); 5300 summary->set_in(1, Location::WritableRegisterOrSmiConstant(right()));
5344 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 5301 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5345 Location::RequiresRegister())); 5302 Location::RequiresRegister()));
5346 return summary; 5303 return summary;
5347 } 5304 }
5348 5305
5349 5306
5350 static const intptr_t kMintShiftCountLimit = 63; 5307 static const intptr_t kMintShiftCountLimit = 63;
5351 5308
5352 bool ShiftMintOpInstr::has_shift_count_check() const { 5309 bool ShiftMintOpInstr::has_shift_count_check() const {
5353 return !RangeUtils::IsWithin( 5310 return !RangeUtils::IsWithin(right()->definition()->range(), 0,
5354 right()->definition()->range(), 0, kMintShiftCountLimit); 5311 kMintShiftCountLimit);
5355 } 5312 }
5356 5313
5357 5314
5358 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5315 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5359 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 5316 PairLocation* left_pair = locs()->in(0).AsPairLocation();
5360 Register left_lo = left_pair->At(0).reg(); 5317 Register left_lo = left_pair->At(0).reg();
5361 Register left_hi = left_pair->At(1).reg(); 5318 Register left_hi = left_pair->At(1).reg();
5362 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 5319 PairLocation* out_pair = locs()->out(0).AsPairLocation();
5363 Register out_lo = out_pair->At(0).reg(); 5320 Register out_lo = out_pair->At(0).reg();
5364 Register out_hi = out_pair->At(1).reg(); 5321 Register out_hi = out_pair->At(1).reg();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
5431 // Code below assumes shift amount is not 0 (cannot shift by 32 - 0). 5388 // Code below assumes shift amount is not 0 (cannot shift by 32 - 0).
5432 Label non_zero_shift, done; 5389 Label non_zero_shift, done;
5433 __ bne(shift, ZR, &non_zero_shift); 5390 __ bne(shift, ZR, &non_zero_shift);
5434 __ delay_slot()->mov(out_lo, left_lo); 5391 __ delay_slot()->mov(out_lo, left_lo);
5435 __ b(&done); 5392 __ b(&done);
5436 __ delay_slot()->mov(out_hi, left_hi); 5393 __ delay_slot()->mov(out_hi, left_hi);
5437 __ Bind(&non_zero_shift); 5394 __ Bind(&non_zero_shift);
5438 5395
5439 // Deopt if shift is larger than 63 or less than 0. 5396 // Deopt if shift is larger than 63 or less than 0.
5440 if (has_shift_count_check()) { 5397 if (has_shift_count_check()) {
5441 __ sltiu(CMPRES1, shift, Immediate(2*(kMintShiftCountLimit + 1))); 5398 __ sltiu(CMPRES1, shift, Immediate(2 * (kMintShiftCountLimit + 1)));
5442 __ beq(CMPRES1, ZR, deopt); 5399 __ beq(CMPRES1, ZR, deopt);
5443 // Untag shift count. 5400 // Untag shift count.
5444 __ delay_slot()->SmiUntag(shift); 5401 __ delay_slot()->SmiUntag(shift);
5445 } else { 5402 } else {
5446 // Untag shift count. 5403 // Untag shift count.
5447 __ SmiUntag(shift); 5404 __ SmiUntag(shift);
5448 } 5405 }
5449 5406
5450 switch (op_kind()) { 5407 switch (op_kind()) {
5451 case Token::kSHR: { 5408 case Token::kSHR: {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5515 } 5472 }
5516 __ Bind(&done); 5473 __ Bind(&done);
5517 } 5474 }
5518 } 5475 }
5519 5476
5520 5477
5521 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, 5478 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone,
5522 bool opt) const { 5479 bool opt) const {
5523 const intptr_t kNumInputs = 1; 5480 const intptr_t kNumInputs = 1;
5524 const intptr_t kNumTemps = 0; 5481 const intptr_t kNumTemps = 0;
5525 LocationSummary* summary = new(zone) LocationSummary( 5482 LocationSummary* summary = new (zone)
5526 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5483 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5527 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5484 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5528 Location::RequiresRegister())); 5485 Location::RequiresRegister()));
5529 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 5486 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5530 Location::RequiresRegister())); 5487 Location::RequiresRegister()));
5531 return summary; 5488 return summary;
5532 } 5489 }
5533 5490
5534 5491
5535 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5492 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5536 ASSERT(op_kind() == Token::kBIT_NOT); 5493 ASSERT(op_kind() == Token::kBIT_NOT);
(...skipping 22 matching lines...) Expand all
5559 5516
5560 CompileType UnaryUint32OpInstr::ComputeType() const { 5517 CompileType UnaryUint32OpInstr::ComputeType() const {
5561 return CompileType::Int(); 5518 return CompileType::Int();
5562 } 5519 }
5563 5520
5564 5521
5565 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Zone* zone, 5522 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Zone* zone,
5566 bool opt) const { 5523 bool opt) const {
5567 const intptr_t kNumInputs = 2; 5524 const intptr_t kNumInputs = 2;
5568 const intptr_t kNumTemps = 0; 5525 const intptr_t kNumTemps = 0;
5569 LocationSummary* summary = new(zone) LocationSummary( 5526 LocationSummary* summary = new (zone)
5570 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5527 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5571 summary->set_in(0, Location::RequiresRegister()); 5528 summary->set_in(0, Location::RequiresRegister());
5572 summary->set_in(1, Location::RequiresRegister()); 5529 summary->set_in(1, Location::RequiresRegister());
5573 summary->set_out(0, Location::RequiresRegister()); 5530 summary->set_out(0, Location::RequiresRegister());
5574 return summary; 5531 return summary;
5575 } 5532 }
5576 5533
5577 5534
5578 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5535 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5579 Register left = locs()->in(0).reg(); 5536 Register left = locs()->in(0).reg();
5580 Register right = locs()->in(1).reg(); 5537 Register right = locs()->in(1).reg();
(...skipping 22 matching lines...) Expand all
5603 default: 5560 default:
5604 UNREACHABLE(); 5561 UNREACHABLE();
5605 } 5562 }
5606 } 5563 }
5607 5564
5608 5565
5609 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Zone* zone, 5566 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Zone* zone,
5610 bool opt) const { 5567 bool opt) const {
5611 const intptr_t kNumInputs = 2; 5568 const intptr_t kNumInputs = 2;
5612 const intptr_t kNumTemps = 1; 5569 const intptr_t kNumTemps = 1;
5613 LocationSummary* summary = new(zone) LocationSummary( 5570 LocationSummary* summary = new (zone)
5614 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5571 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5615 summary->set_in(0, Location::RequiresRegister()); 5572 summary->set_in(0, Location::RequiresRegister());
5616 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 5573 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
5617 summary->set_temp(0, Location::RequiresRegister()); 5574 summary->set_temp(0, Location::RequiresRegister());
5618 summary->set_out(0, Location::RequiresRegister()); 5575 summary->set_out(0, Location::RequiresRegister());
5619 return summary; 5576 return summary;
5620 } 5577 }
5621 5578
5622 5579
5623 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5580 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5624 const intptr_t kShifterLimit = 31; 5581 const intptr_t kShifterLimit = 31;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
5672 default: 5629 default:
5673 UNREACHABLE(); 5630 UNREACHABLE();
5674 } 5631 }
5675 } 5632 }
5676 5633
5677 5634
5678 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Zone* zone, 5635 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Zone* zone,
5679 bool opt) const { 5636 bool opt) const {
5680 const intptr_t kNumInputs = 1; 5637 const intptr_t kNumInputs = 1;
5681 const intptr_t kNumTemps = 0; 5638 const intptr_t kNumTemps = 0;
5682 LocationSummary* summary = new(zone) LocationSummary( 5639 LocationSummary* summary = new (zone)
5683 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5640 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5684 summary->set_in(0, Location::RequiresRegister()); 5641 summary->set_in(0, Location::RequiresRegister());
5685 summary->set_out(0, Location::RequiresRegister()); 5642 summary->set_out(0, Location::RequiresRegister());
5686 return summary; 5643 return summary;
5687 } 5644 }
5688 5645
5689 5646
5690 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5647 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5691 Register left = locs()->in(0).reg(); 5648 Register left = locs()->in(0).reg();
5692 Register out = locs()->out(0).reg(); 5649 Register out = locs()->out(0).reg();
5693 ASSERT(left != out); 5650 ASSERT(left != out);
5694 5651
5695 ASSERT(op_kind() == Token::kBIT_NOT); 5652 ASSERT(op_kind() == Token::kBIT_NOT);
5696 5653
5697 __ nor(out, ZR, left); 5654 __ nor(out, ZR, left);
5698 } 5655 }
5699 5656
5700 5657
5701 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5658 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5702 5659
5703 5660
5704 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, 5661 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone,
5705 bool opt) const { 5662 bool opt) const {
5706 const intptr_t kNumInputs = 1; 5663 const intptr_t kNumInputs = 1;
5707 const intptr_t kNumTemps = 0; 5664 const intptr_t kNumTemps = 0;
5708 LocationSummary* summary = new(zone) LocationSummary( 5665 LocationSummary* summary = new (zone)
5709 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5666 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5710 if (from() == kUnboxedMint) { 5667 if (from() == kUnboxedMint) {
5711 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); 5668 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
5712 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5669 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5713 Location::RequiresRegister())); 5670 Location::RequiresRegister()));
5714 summary->set_out(0, Location::RequiresRegister()); 5671 summary->set_out(0, Location::RequiresRegister());
5715 } else if (to() == kUnboxedMint) { 5672 } else if (to() == kUnboxedMint) {
5716 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); 5673 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5717 summary->set_in(0, Location::RequiresRegister()); 5674 summary->set_in(0, Location::RequiresRegister());
5718 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 5675 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
5719 Location::RequiresRegister())); 5676 Location::RequiresRegister()));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5769 } else { 5726 } else {
5770 ASSERT(from() == kUnboxedInt32); 5727 ASSERT(from() == kUnboxedInt32);
5771 __ sra(out_hi, in, 31); 5728 __ sra(out_hi, in, 31);
5772 } 5729 }
5773 } else { 5730 } else {
5774 UNREACHABLE(); 5731 UNREACHABLE();
5775 } 5732 }
5776 } 5733 }
5777 5734
5778 5735
5779 LocationSummary* ThrowInstr::MakeLocationSummary(Zone* zone, 5736 LocationSummary* ThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const {
5780 bool opt) const { 5737 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
5781 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
5782 } 5738 }
5783 5739
5784 5740
5785
5786 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5741 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5787 compiler->GenerateRuntimeCall(token_pos(), 5742 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1,
5788 deopt_id(),
5789 kThrowRuntimeEntry,
5790 1,
5791 locs()); 5743 locs());
5792 __ break_(0); 5744 __ break_(0);
5793 } 5745 }
5794 5746
5795 5747
5796 LocationSummary* ReThrowInstr::MakeLocationSummary(Zone* zone, 5748 LocationSummary* ReThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const {
5797 bool opt) const { 5749 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
5798 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
5799 } 5750 }
5800 5751
5801 5752
5802 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5753 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5803 compiler->SetNeedsStacktrace(catch_try_index()); 5754 compiler->SetNeedsStacktrace(catch_try_index());
5804 compiler->GenerateRuntimeCall(token_pos(), 5755 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry,
5805 deopt_id(), 5756 2, locs());
5806 kReThrowRuntimeEntry,
5807 2,
5808 locs());
5809 __ break_(0); 5757 __ break_(0);
5810 } 5758 }
5811 5759
5812 5760
5813 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, 5761 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const {
5814 bool opt) const { 5762 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
5815 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
5816 } 5763 }
5817 5764
5818 5765
5819 void StopInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5766 void StopInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5820 __ Stop(message()); 5767 __ Stop(message());
5821 } 5768 }
5822 5769
5823 5770
5824 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5771 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5825 if (!compiler->CanFallThroughTo(normal_entry())) { 5772 if (!compiler->CanFallThroughTo(normal_entry())) {
5826 __ b(compiler->GetJumpLabel(normal_entry())); 5773 __ b(compiler->GetJumpLabel(normal_entry()));
5827 } 5774 }
5828 } 5775 }
5829 5776
5830 5777
5831 LocationSummary* GotoInstr::MakeLocationSummary(Zone* zone, 5778 LocationSummary* GotoInstr::MakeLocationSummary(Zone* zone, bool opt) const {
5832 bool opt) const { 5779 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
5833 return new(zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
5834 } 5780 }
5835 5781
5836 5782
5837 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5783 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5838 __ Comment("GotoInstr"); 5784 __ Comment("GotoInstr");
5839 if (!compiler->is_optimizing()) { 5785 if (!compiler->is_optimizing()) {
5840 if (FLAG_reorder_basic_blocks) { 5786 if (FLAG_reorder_basic_blocks) {
5841 compiler->EmitEdgeCounter(block()->preorder_number()); 5787 compiler->EmitEdgeCounter(block()->preorder_number());
5842 } 5788 }
5843 // Add a deoptimization descriptor for deoptimizing instructions that 5789 // Add a deoptimization descriptor for deoptimizing instructions that
5844 // may be inserted before this instruction. 5790 // may be inserted before this instruction.
5845 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, 5791 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
5846 GetDeoptId(),
5847 TokenPosition::kNoSource); 5792 TokenPosition::kNoSource);
5848 } 5793 }
5849 if (HasParallelMove()) { 5794 if (HasParallelMove()) {
5850 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 5795 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
5851 } 5796 }
5852 5797
5853 // We can fall through if the successor is the next block in the list. 5798 // We can fall through if the successor is the next block in the list.
5854 // Otherwise, we need a jump. 5799 // Otherwise, we need a jump.
5855 if (!compiler->CanFallThroughTo(successor())) { 5800 if (!compiler->CanFallThroughTo(successor())) {
5856 __ b(compiler->GetJumpLabel(successor())); 5801 __ b(compiler->GetJumpLabel(successor()));
5857 } 5802 }
5858 } 5803 }
5859 5804
5860 5805
5861 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone, 5806 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone,
5862 bool opt) const { 5807 bool opt) const {
5863 const intptr_t kNumInputs = 1; 5808 const intptr_t kNumInputs = 1;
5864 const intptr_t kNumTemps = 1; 5809 const intptr_t kNumTemps = 1;
5865 5810
5866 LocationSummary* summary = new(zone) LocationSummary( 5811 LocationSummary* summary = new (zone)
5867 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5812 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5868 5813
5869 summary->set_in(0, Location::RequiresRegister()); 5814 summary->set_in(0, Location::RequiresRegister());
5870 summary->set_temp(0, Location::RequiresRegister()); 5815 summary->set_temp(0, Location::RequiresRegister());
5871 5816
5872 return summary; 5817 return summary;
5873 } 5818 }
5874 5819
5875 5820
5876 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5821 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5877 Register target_reg = locs()->temp_slot(0)->reg(); 5822 Register target_reg = locs()->temp_slot(0)->reg();
5878 5823
5879 __ GetNextPC(target_reg, TMP); 5824 __ GetNextPC(target_reg, TMP);
5880 const intptr_t entry_offset = 5825 const intptr_t entry_offset = __ CodeSize() - 1 * Instr::kInstrSize;
5881 __ CodeSize() - 1 * Instr::kInstrSize;
5882 __ AddImmediate(target_reg, target_reg, -entry_offset); 5826 __ AddImmediate(target_reg, target_reg, -entry_offset);
5883 5827
5884 // Add the offset. 5828 // Add the offset.
5885 Register offset_reg = locs()->in(0).reg(); 5829 Register offset_reg = locs()->in(0).reg();
5886 if (offset()->definition()->representation() == kTagged) { 5830 if (offset()->definition()->representation() == kTagged) {
5887 __ SmiUntag(offset_reg); 5831 __ SmiUntag(offset_reg);
5888 } 5832 }
5889 __ addu(target_reg, target_reg, offset_reg); 5833 __ addu(target_reg, target_reg, offset_reg);
5890 5834
5891 // Jump to the absolute address. 5835 // Jump to the absolute address.
5892 __ jr(target_reg); 5836 __ jr(target_reg);
5893 } 5837 }
5894 5838
5895 5839
5896 LocationSummary* StrictCompareInstr::MakeLocationSummary(Zone* zone, 5840 LocationSummary* StrictCompareInstr::MakeLocationSummary(Zone* zone,
5897 bool opt) const { 5841 bool opt) const {
5898 const intptr_t kNumInputs = 2; 5842 const intptr_t kNumInputs = 2;
5899 const intptr_t kNumTemps = 0; 5843 const intptr_t kNumTemps = 0;
5900 if (needs_number_check()) { 5844 if (needs_number_check()) {
5901 LocationSummary* locs = new(zone) LocationSummary( 5845 LocationSummary* locs = new (zone)
5902 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 5846 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
5903 locs->set_in(0, Location::RegisterLocation(A0)); 5847 locs->set_in(0, Location::RegisterLocation(A0));
5904 locs->set_in(1, Location::RegisterLocation(A1)); 5848 locs->set_in(1, Location::RegisterLocation(A1));
5905 locs->set_out(0, Location::RegisterLocation(A0)); 5849 locs->set_out(0, Location::RegisterLocation(A0));
5906 return locs; 5850 return locs;
5907 } 5851 }
5908 LocationSummary* locs = new(zone) LocationSummary( 5852 LocationSummary* locs = new (zone)
5909 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5853 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5910 locs->set_in(0, Location::RegisterOrConstant(left())); 5854 locs->set_in(0, Location::RegisterOrConstant(left()));
5911 // Only one of the inputs can be a constant. Choose register if the first one 5855 // Only one of the inputs can be a constant. Choose register if the first one
5912 // is a constant. 5856 // is a constant.
5913 locs->set_in(1, locs->in(0).IsConstant() 5857 locs->set_in(1, locs->in(0).IsConstant()
5914 ? Location::RequiresRegister() 5858 ? Location::RequiresRegister()
5915 : Location::RegisterOrConstant(right())); 5859 : Location::RegisterOrConstant(right()));
5916 locs->set_out(0, Location::RequiresRegister()); 5860 locs->set_out(0, Location::RequiresRegister());
5917 return locs; 5861 return locs;
5918 } 5862 }
5919 5863
5920 5864
5921 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 5865 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
5922 BranchLabels labels) { 5866 BranchLabels labels) {
5923 Location left = locs()->in(0); 5867 Location left = locs()->in(0);
5924 Location right = locs()->in(1); 5868 Location right = locs()->in(1);
5925 ASSERT(!left.IsConstant() || !right.IsConstant()); 5869 ASSERT(!left.IsConstant() || !right.IsConstant());
5926 Condition true_condition; 5870 Condition true_condition;
5927 if (left.IsConstant()) { 5871 if (left.IsConstant()) {
5928 true_condition = compiler->EmitEqualityRegConstCompare(right.reg(), 5872 true_condition = compiler->EmitEqualityRegConstCompare(
5929 left.constant(), 5873 right.reg(), left.constant(), needs_number_check(), token_pos());
5930 needs_number_check(),
5931 token_pos());
5932 } else if (right.IsConstant()) { 5874 } else if (right.IsConstant()) {
5933 true_condition = compiler->EmitEqualityRegConstCompare(left.reg(), 5875 true_condition = compiler->EmitEqualityRegConstCompare(
5934 right.constant(), 5876 left.reg(), right.constant(), needs_number_check(), token_pos());
5935 needs_number_check(),
5936 token_pos());
5937 } else { 5877 } else {
5938 true_condition = compiler->EmitEqualityRegRegCompare(left.reg(), 5878 true_condition = compiler->EmitEqualityRegRegCompare(
5939 right.reg(), 5879 left.reg(), right.reg(), needs_number_check(), token_pos());
5940 needs_number_check(),
5941 token_pos());
5942 } 5880 }
5943 if (kind() != Token::kEQ_STRICT) { 5881 if (kind() != Token::kEQ_STRICT) {
5944 ASSERT(kind() == Token::kNE_STRICT); 5882 ASSERT(kind() == Token::kNE_STRICT);
5945 true_condition = NegateCondition(true_condition); 5883 true_condition = NegateCondition(true_condition);
5946 } 5884 }
5947 return true_condition; 5885 return true_condition;
5948 } 5886 }
5949 5887
5950 5888
5951 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5889 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5952 __ Comment("StrictCompareInstr"); 5890 __ Comment("StrictCompareInstr");
5953 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5891 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5954 5892
5955 Label is_true, is_false; 5893 Label is_true, is_false;
5956 BranchLabels labels = { &is_true, &is_false, &is_false }; 5894 BranchLabels labels = {&is_true, &is_false, &is_false};
5957 Condition true_condition = EmitComparisonCode(compiler, labels); 5895 Condition true_condition = EmitComparisonCode(compiler, labels);
5958 EmitBranchOnCondition(compiler, true_condition, labels); 5896 EmitBranchOnCondition(compiler, true_condition, labels);
5959 5897
5960 Register result = locs()->out(0).reg(); 5898 Register result = locs()->out(0).reg();
5961 Label done; 5899 Label done;
5962 __ Bind(&is_false); 5900 __ Bind(&is_false);
5963 __ LoadObject(result, Bool::False()); 5901 __ LoadObject(result, Bool::False());
5964 __ b(&done); 5902 __ b(&done);
5965 __ Bind(&is_true); 5903 __ Bind(&is_true);
5966 __ LoadObject(result, Bool::True()); 5904 __ LoadObject(result, Bool::True());
5967 __ Bind(&done); 5905 __ Bind(&done);
5968 } 5906 }
5969 5907
5970 5908
5971 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 5909 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
5972 BranchInstr* branch) { 5910 BranchInstr* branch) {
5973 __ Comment("StrictCompareInstr::EmitBranchCode"); 5911 __ Comment("StrictCompareInstr::EmitBranchCode");
5974 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5912 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5975 5913
5976 BranchLabels labels = compiler->CreateBranchLabels(branch); 5914 BranchLabels labels = compiler->CreateBranchLabels(branch);
5977 Condition true_condition = EmitComparisonCode(compiler, labels); 5915 Condition true_condition = EmitComparisonCode(compiler, labels);
5978 EmitBranchOnCondition(compiler, true_condition, labels); 5916 EmitBranchOnCondition(compiler, true_condition, labels);
5979 } 5917 }
5980 5918
5981 5919
5982 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone, 5920 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
5983 bool opt) const { 5921 bool opt) const {
5984 return LocationSummary::Make(zone, 5922 return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
5985 1,
5986 Location::RequiresRegister(),
5987 LocationSummary::kNoCall); 5923 LocationSummary::kNoCall);
5988 } 5924 }
5989 5925
5990 5926
5991 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5927 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5992 Register value = locs()->in(0).reg(); 5928 Register value = locs()->in(0).reg();
5993 Register result = locs()->out(0).reg(); 5929 Register result = locs()->out(0).reg();
5994 5930
5995 __ LoadObject(result, Bool::True()); 5931 __ LoadObject(result, Bool::True());
5996 __ LoadObject(TMP, Bool::False()); 5932 __ LoadObject(TMP, Bool::False());
5997 __ subu(CMPRES1, value, result); 5933 __ subu(CMPRES1, value, result);
5998 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. 5934 __ movz(result, TMP, CMPRES1); // If value is True, move False into result.
5999 } 5935 }
6000 5936
6001 5937
6002 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone, 5938 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
6003 bool opt) const { 5939 bool opt) const {
6004 return MakeCallSummary(zone); 5940 return MakeCallSummary(zone);
6005 } 5941 }
6006 5942
6007 5943
6008 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5944 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6009 __ Comment("AllocateObjectInstr"); 5945 __ Comment("AllocateObjectInstr");
6010 const Code& stub = Code::ZoneHandle( 5946 const Code& stub = Code::ZoneHandle(
6011 compiler->zone(), StubCode::GetAllocationStubForClass(cls())); 5947 compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
6012 const StubEntry stub_entry(stub); 5948 const StubEntry stub_entry(stub);
6013 compiler->GenerateCall(token_pos(), 5949 compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther,
6014 stub_entry,
6015 RawPcDescriptors::kOther,
6016 locs()); 5950 locs());
6017 compiler->AddStubCallTarget(stub); 5951 compiler->AddStubCallTarget(stub);
6018 __ Drop(ArgumentCount()); // Discard arguments. 5952 __ Drop(ArgumentCount()); // Discard arguments.
6019 } 5953 }
6020 5954
6021 5955
6022 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5956 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6023 ASSERT(!compiler->is_optimizing()); 5957 ASSERT(!compiler->is_optimizing());
6024 __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry()); 5958 __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry());
6025 compiler->AddCurrentDescriptor(stub_kind_, Thread::kNoDeoptId, token_pos()); 5959 compiler->AddCurrentDescriptor(stub_kind_, Thread::kNoDeoptId, token_pos());
6026 compiler->RecordSafepoint(locs()); 5960 compiler->RecordSafepoint(locs());
6027 } 5961 }
6028 5962
6029 5963
6030 LocationSummary* GrowRegExpStackInstr::MakeLocationSummary( 5964 LocationSummary* GrowRegExpStackInstr::MakeLocationSummary(Zone* zone,
6031 Zone* zone, bool opt) const { 5965 bool opt) const {
6032 const intptr_t kNumInputs = 1; 5966 const intptr_t kNumInputs = 1;
6033 const intptr_t kNumTemps = 0; 5967 const intptr_t kNumTemps = 0;
6034 LocationSummary* locs = new(zone) LocationSummary( 5968 LocationSummary* locs = new (zone)
6035 zone, kNumInputs, kNumTemps, LocationSummary::kCall); 5969 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
6036 locs->set_in(0, Location::RegisterLocation(T0)); 5970 locs->set_in(0, Location::RegisterLocation(T0));
6037 locs->set_out(0, Location::RegisterLocation(T0)); 5971 locs->set_out(0, Location::RegisterLocation(T0));
6038 return locs; 5972 return locs;
6039 } 5973 }
6040 5974
6041 5975
6042 void GrowRegExpStackInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5976 void GrowRegExpStackInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6043 const Register typed_data = locs()->in(0).reg(); 5977 const Register typed_data = locs()->in(0).reg();
6044 const Register result = locs()->out(0).reg(); 5978 const Register result = locs()->out(0).reg();
6045 __ Comment("GrowRegExpStackInstr"); 5979 __ Comment("GrowRegExpStackInstr");
6046 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 5980 __ addiu(SP, SP, Immediate(-2 * kWordSize));
6047 __ LoadObject(TMP, Object::null_object()); 5981 __ LoadObject(TMP, Object::null_object());
6048 __ sw(TMP, Address(SP, 1 * kWordSize)); 5982 __ sw(TMP, Address(SP, 1 * kWordSize));
6049 __ sw(typed_data, Address(SP, 0 * kWordSize)); 5983 __ sw(typed_data, Address(SP, 0 * kWordSize));
6050 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, 5984 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
6051 deopt_id(), 5985 kGrowRegExpStackRuntimeEntry, 1, locs());
6052 kGrowRegExpStackRuntimeEntry,
6053 1,
6054 locs());
6055 __ lw(result, Address(SP, 1 * kWordSize)); 5986 __ lw(result, Address(SP, 1 * kWordSize));
6056 __ addiu(SP, SP, Immediate(2 * kWordSize)); 5987 __ addiu(SP, SP, Immediate(2 * kWordSize));
6057 } 5988 }
6058 5989
6059 5990
6060 } // namespace dart 5991 } // namespace dart
6061 5992
6062 #endif // defined TARGET_ARCH_MIPS 5993 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698