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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months 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_dbc.cc ('k') | runtime/vm/intermediate_language_test.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 18 matching lines...) Expand all
29 // on the stack and return the result in a fixed register EAX. 29 // on the stack and return the result in a fixed register EAX.
30 LocationSummary* Instruction::MakeCallSummary(Zone* zone) { 30 LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
31 const intptr_t kNumInputs = 0; 31 const intptr_t kNumInputs = 0;
32 const intptr_t kNumTemps = 0; 32 const intptr_t kNumTemps = 0;
33 LocationSummary* result = new (zone) 33 LocationSummary* result = new (zone)
34 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 34 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
35 result->set_out(0, Location::RegisterLocation(EAX)); 35 result->set_out(0, Location::RegisterLocation(EAX));
36 return result; 36 return result;
37 } 37 }
38 38
39
40 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone, 39 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone,
41 bool opt) const { 40 bool opt) const {
42 const intptr_t kNumInputs = 1; 41 const intptr_t kNumInputs = 1;
43 const intptr_t kNumTemps = 0; 42 const intptr_t kNumTemps = 0;
44 LocationSummary* locs = new (zone) 43 LocationSummary* locs = new (zone)
45 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 44 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
46 locs->set_in(0, Location::AnyOrConstant(value())); 45 locs->set_in(0, Location::AnyOrConstant(value()));
47 return locs; 46 return locs;
48 } 47 }
49 48
50
51 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 49 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
52 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode 50 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode
53 // where PushArgument is handled by BindInstr::EmitNativeCode. 51 // where PushArgument is handled by BindInstr::EmitNativeCode.
54 if (compiler->is_optimizing()) { 52 if (compiler->is_optimizing()) {
55 Location value = locs()->in(0); 53 Location value = locs()->in(0);
56 if (value.IsRegister()) { 54 if (value.IsRegister()) {
57 __ pushl(value.reg()); 55 __ pushl(value.reg());
58 } else if (value.IsConstant()) { 56 } else if (value.IsConstant()) {
59 __ PushObject(value.constant()); 57 __ PushObject(value.constant());
60 } else { 58 } else {
61 ASSERT(value.IsStackSlot()); 59 ASSERT(value.IsStackSlot());
62 __ pushl(value.ToStackSlotAddress()); 60 __ pushl(value.ToStackSlotAddress());
63 } 61 }
64 } 62 }
65 } 63 }
66 64
67
68 LocationSummary* ReturnInstr::MakeLocationSummary(Zone* zone, bool opt) const { 65 LocationSummary* ReturnInstr::MakeLocationSummary(Zone* zone, bool opt) const {
69 const intptr_t kNumInputs = 1; 66 const intptr_t kNumInputs = 1;
70 const intptr_t kNumTemps = 0; 67 const intptr_t kNumTemps = 0;
71 LocationSummary* locs = new (zone) 68 LocationSummary* locs = new (zone)
72 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 69 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
73 locs->set_in(0, Location::RegisterLocation(EAX)); 70 locs->set_in(0, Location::RegisterLocation(EAX));
74 return locs; 71 return locs;
75 } 72 }
76 73
77
78 // Attempt optimized compilation at return instruction instead of at the entry. 74 // Attempt optimized compilation at return instruction instead of at the entry.
79 // The entry needs to be patchable, no inlined objects are allowed in the area 75 // The entry needs to be patchable, no inlined objects are allowed in the area
80 // that will be overwritten by the patch instruction: a jump). 76 // that will be overwritten by the patch instruction: a jump).
81 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 77 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
82 Register result = locs()->in(0).reg(); 78 Register result = locs()->in(0).reg();
83 ASSERT(result == EAX); 79 ASSERT(result == EAX);
84 80
85 if (compiler->intrinsic_mode()) { 81 if (compiler->intrinsic_mode()) {
86 // Intrinsics don't have a frame. 82 // Intrinsics don't have a frame.
87 __ ret(); 83 __ ret();
(...skipping 10 matching lines...) Expand all
98 __ subl(EDI, EBP); 94 __ subl(EDI, EBP);
99 __ cmpl(EDI, Immediate(fp_sp_dist)); 95 __ cmpl(EDI, Immediate(fp_sp_dist));
100 __ j(EQUAL, &done, Assembler::kNearJump); 96 __ j(EQUAL, &done, Assembler::kNearJump);
101 __ int3(); 97 __ int3();
102 __ Bind(&done); 98 __ Bind(&done);
103 #endif 99 #endif
104 __ LeaveFrame(); 100 __ LeaveFrame();
105 __ ret(); 101 __ ret();
106 } 102 }
107 103
108
109 LocationSummary* LoadLocalInstr::MakeLocationSummary(Zone* zone, 104 LocationSummary* LoadLocalInstr::MakeLocationSummary(Zone* zone,
110 bool opt) const { 105 bool opt) const {
111 const intptr_t kNumInputs = 0; 106 const intptr_t kNumInputs = 0;
112 const intptr_t stack_index = (local().index() < 0) 107 const intptr_t stack_index = (local().index() < 0)
113 ? kFirstLocalSlotFromFp - local().index() 108 ? kFirstLocalSlotFromFp - local().index()
114 : kParamEndSlotFromFp - local().index(); 109 : kParamEndSlotFromFp - local().index();
115 return LocationSummary::Make(zone, kNumInputs, 110 return LocationSummary::Make(zone, kNumInputs,
116 Location::StackSlot(stack_index), 111 Location::StackSlot(stack_index),
117 LocationSummary::kNoCall); 112 LocationSummary::kNoCall);
118 } 113 }
119 114
120
121 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 115 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
122 ASSERT(!compiler->is_optimizing()); 116 ASSERT(!compiler->is_optimizing());
123 // Nothing to do. 117 // Nothing to do.
124 } 118 }
125 119
126
127 LocationSummary* StoreLocalInstr::MakeLocationSummary(Zone* zone, 120 LocationSummary* StoreLocalInstr::MakeLocationSummary(Zone* zone,
128 bool opt) const { 121 bool opt) const {
129 const intptr_t kNumInputs = 1; 122 const intptr_t kNumInputs = 1;
130 return LocationSummary::Make(zone, kNumInputs, Location::SameAsFirstInput(), 123 return LocationSummary::Make(zone, kNumInputs, Location::SameAsFirstInput(),
131 LocationSummary::kNoCall); 124 LocationSummary::kNoCall);
132 } 125 }
133 126
134
135 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 127 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
136 Register value = locs()->in(0).reg(); 128 Register value = locs()->in(0).reg();
137 Register result = locs()->out(0).reg(); 129 Register result = locs()->out(0).reg();
138 ASSERT(result == value); // Assert that register assignment is correct. 130 ASSERT(result == value); // Assert that register assignment is correct.
139 __ movl(Address(EBP, local().index() * kWordSize), value); 131 __ movl(Address(EBP, local().index() * kWordSize), value);
140 } 132 }
141 133
142
143 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone, 134 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone,
144 bool opt) const { 135 bool opt) const {
145 const intptr_t kNumInputs = 0; 136 const intptr_t kNumInputs = 0;
146 return LocationSummary::Make(zone, kNumInputs, 137 return LocationSummary::Make(zone, kNumInputs,
147 Assembler::IsSafe(value()) 138 Assembler::IsSafe(value())
148 ? Location::Constant(this) 139 ? Location::Constant(this)
149 : Location::RequiresRegister(), 140 : Location::RequiresRegister(),
150 LocationSummary::kNoCall); 141 LocationSummary::kNoCall);
151 } 142 }
152 143
153
154 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 144 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
155 // The register allocator drops constant definitions that have no uses. 145 // The register allocator drops constant definitions that have no uses.
156 Location out = locs()->out(0); 146 Location out = locs()->out(0);
157 ASSERT(out.IsRegister() || out.IsConstant() || out.IsInvalid()); 147 ASSERT(out.IsRegister() || out.IsConstant() || out.IsInvalid());
158 if (out.IsRegister()) { 148 if (out.IsRegister()) {
159 Register result = out.reg(); 149 Register result = out.reg();
160 __ LoadObjectSafely(result, value()); 150 __ LoadObjectSafely(result, value());
161 } 151 }
162 } 152 }
163 153
164
165 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Zone* zone, 154 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Zone* zone,
166 bool opt) const { 155 bool opt) const {
167 const intptr_t kNumInputs = 0; 156 const intptr_t kNumInputs = 0;
168 const intptr_t kNumTemps = 157 const intptr_t kNumTemps =
169 (constant_address() == 0) && (representation() != kUnboxedInt32) ? 1 : 0; 158 (constant_address() == 0) && (representation() != kUnboxedInt32) ? 1 : 0;
170 LocationSummary* locs = new (zone) 159 LocationSummary* locs = new (zone)
171 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 160 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
172 if (representation() == kUnboxedDouble) { 161 if (representation() == kUnboxedDouble) {
173 locs->set_out(0, Location::RequiresFpuRegister()); 162 locs->set_out(0, Location::RequiresFpuRegister());
174 } else { 163 } else {
175 ASSERT(representation() == kUnboxedInt32); 164 ASSERT(representation() == kUnboxedInt32);
176 locs->set_out(0, Location::RequiresRegister()); 165 locs->set_out(0, Location::RequiresRegister());
177 } 166 }
178 if (kNumTemps == 1) { 167 if (kNumTemps == 1) {
179 locs->set_temp(0, Location::RequiresRegister()); 168 locs->set_temp(0, Location::RequiresRegister());
180 } 169 }
181 return locs; 170 return locs;
182 } 171 }
183 172
184
185 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 173 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
186 // The register allocator drops constant definitions that have no uses. 174 // The register allocator drops constant definitions that have no uses.
187 if (!locs()->out(0).IsInvalid()) { 175 if (!locs()->out(0).IsInvalid()) {
188 switch (representation()) { 176 switch (representation()) {
189 case kUnboxedDouble: { 177 case kUnboxedDouble: {
190 XmmRegister result = locs()->out(0).fpu_reg(); 178 XmmRegister result = locs()->out(0).fpu_reg();
191 if (constant_address() == 0) { 179 if (constant_address() == 0) {
192 Register boxed = locs()->temp(0).reg(); 180 Register boxed = locs()->temp(0).reg();
193 __ LoadObjectSafely(boxed, value()); 181 __ LoadObjectSafely(boxed, value());
194 __ movsd(result, FieldAddress(boxed, Double::value_offset())); 182 __ movsd(result, FieldAddress(boxed, Double::value_offset()));
195 } else if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { 183 } else if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) {
196 __ xorps(result, result); 184 __ xorps(result, result);
197 } else { 185 } else {
198 __ movsd(result, Address::Absolute(constant_address())); 186 __ movsd(result, Address::Absolute(constant_address()));
199 } 187 }
200 break; 188 break;
201 } 189 }
202 case kUnboxedInt32: 190 case kUnboxedInt32:
203 __ movl(locs()->out(0).reg(), Immediate(Smi::Cast(value()).Value())); 191 __ movl(locs()->out(0).reg(), Immediate(Smi::Cast(value()).Value()));
204 break; 192 break;
205 default: 193 default:
206 UNREACHABLE(); 194 UNREACHABLE();
207 } 195 }
208 } 196 }
209 } 197 }
210 198
211
212 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, 199 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
213 bool opt) const { 200 bool opt) const {
214 const intptr_t kNumInputs = 3; 201 const intptr_t kNumInputs = 3;
215 const intptr_t kNumTemps = 0; 202 const intptr_t kNumTemps = 0;
216 LocationSummary* summary = new (zone) 203 LocationSummary* summary = new (zone)
217 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 204 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
218 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. 205 summary->set_in(0, Location::RegisterLocation(EAX)); // Value.
219 summary->set_in(1, Location::RegisterLocation(EDX)); // Instant. type args. 206 summary->set_in(1, Location::RegisterLocation(EDX)); // Instant. type args.
220 summary->set_in(2, Location::RegisterLocation(ECX)); // Function type args. 207 summary->set_in(2, Location::RegisterLocation(ECX)); // Function type args.
221 summary->set_out(0, Location::RegisterLocation(EAX)); 208 summary->set_out(0, Location::RegisterLocation(EAX));
222 return summary; 209 return summary;
223 } 210 }
224 211
225
226 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, 212 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone,
227 bool opt) const { 213 bool opt) const {
228 const intptr_t kNumInputs = 1; 214 const intptr_t kNumInputs = 1;
229 const intptr_t kNumTemps = 0; 215 const intptr_t kNumTemps = 0;
230 LocationSummary* locs = new (zone) 216 LocationSummary* locs = new (zone)
231 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 217 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
232 locs->set_in(0, Location::RegisterLocation(EAX)); 218 locs->set_in(0, Location::RegisterLocation(EAX));
233 locs->set_out(0, Location::RegisterLocation(EAX)); 219 locs->set_out(0, Location::RegisterLocation(EAX));
234 return locs; 220 return locs;
235 } 221 }
236 222
237
238 static void EmitAssertBoolean(Register reg, 223 static void EmitAssertBoolean(Register reg,
239 TokenPosition token_pos, 224 TokenPosition token_pos,
240 intptr_t deopt_id, 225 intptr_t deopt_id,
241 LocationSummary* locs, 226 LocationSummary* locs,
242 FlowGraphCompiler* compiler) { 227 FlowGraphCompiler* compiler) {
243 // Check that the type of the value is allowed in conditional context. 228 // Check that the type of the value is allowed in conditional context.
244 // Call the runtime if the object is not bool::true or bool::false. 229 // Call the runtime if the object is not bool::true or bool::false.
245 ASSERT(locs->always_calls()); 230 ASSERT(locs->always_calls());
246 Label done; 231 Label done;
247 232
248 if (Isolate::Current()->type_checks()) { 233 if (Isolate::Current()->type_checks()) {
249 __ CompareObject(reg, Bool::True()); 234 __ CompareObject(reg, Bool::True());
250 __ j(EQUAL, &done, Assembler::kNearJump); 235 __ j(EQUAL, &done, Assembler::kNearJump);
251 __ CompareObject(reg, Bool::False()); 236 __ CompareObject(reg, Bool::False());
252 __ j(EQUAL, &done, Assembler::kNearJump); 237 __ j(EQUAL, &done, Assembler::kNearJump);
253 } else { 238 } else {
254 ASSERT(Isolate::Current()->asserts()); 239 ASSERT(Isolate::Current()->asserts());
255 __ CompareObject(reg, Object::null_instance()); 240 __ CompareObject(reg, Object::null_instance());
256 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 241 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
257 } 242 }
258 243
259 __ pushl(reg); // Push the source object. 244 __ pushl(reg); // Push the source object.
260 compiler->GenerateRuntimeCall(token_pos, deopt_id, 245 compiler->GenerateRuntimeCall(token_pos, deopt_id,
261 kNonBoolTypeErrorRuntimeEntry, 1, locs); 246 kNonBoolTypeErrorRuntimeEntry, 1, locs);
262 // We should never return here. 247 // We should never return here.
263 __ int3(); 248 __ int3();
264 __ Bind(&done); 249 __ Bind(&done);
265 } 250 }
266 251
267
268 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 252 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
269 Register obj = locs()->in(0).reg(); 253 Register obj = locs()->in(0).reg();
270 Register result = locs()->out(0).reg(); 254 Register result = locs()->out(0).reg();
271 255
272 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 256 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
273 ASSERT(obj == result); 257 ASSERT(obj == result);
274 } 258 }
275 259
276
277 static Condition TokenKindToSmiCondition(Token::Kind kind) { 260 static Condition TokenKindToSmiCondition(Token::Kind kind) {
278 switch (kind) { 261 switch (kind) {
279 case Token::kEQ: 262 case Token::kEQ:
280 return EQUAL; 263 return EQUAL;
281 case Token::kNE: 264 case Token::kNE:
282 return NOT_EQUAL; 265 return NOT_EQUAL;
283 case Token::kLT: 266 case Token::kLT:
284 return LESS; 267 return LESS;
285 case Token::kGT: 268 case Token::kGT:
286 return GREATER; 269 return GREATER;
287 case Token::kLTE: 270 case Token::kLTE:
288 return LESS_EQUAL; 271 return LESS_EQUAL;
289 case Token::kGTE: 272 case Token::kGTE:
290 return GREATER_EQUAL; 273 return GREATER_EQUAL;
291 default: 274 default:
292 UNREACHABLE(); 275 UNREACHABLE();
293 return OVERFLOW; 276 return OVERFLOW;
294 } 277 }
295 } 278 }
296 279
297
298 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Zone* zone, 280 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Zone* zone,
299 bool opt) const { 281 bool opt) const {
300 const intptr_t kNumInputs = 2; 282 const intptr_t kNumInputs = 2;
301 if (operation_cid() == kMintCid) { 283 if (operation_cid() == kMintCid) {
302 const intptr_t kNumTemps = 0; 284 const intptr_t kNumTemps = 0;
303 LocationSummary* locs = new (zone) 285 LocationSummary* locs = new (zone)
304 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 286 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
305 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 287 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
306 Location::RequiresRegister())); 288 Location::RequiresRegister()));
307 locs->set_in(1, Location::Pair(Location::RequiresRegister(), 289 locs->set_in(1, Location::Pair(Location::RequiresRegister(),
(...skipping 21 matching lines...) Expand all
329 locs->set_in(1, locs->in(0).IsConstant() 311 locs->set_in(1, locs->in(0).IsConstant()
330 ? Location::RequiresRegister() 312 ? Location::RequiresRegister()
331 : Location::RegisterOrConstant(right())); 313 : Location::RegisterOrConstant(right()));
332 locs->set_out(0, Location::RequiresRegister()); 314 locs->set_out(0, Location::RequiresRegister());
333 return locs; 315 return locs;
334 } 316 }
335 UNREACHABLE(); 317 UNREACHABLE();
336 return NULL; 318 return NULL;
337 } 319 }
338 320
339
340 static void LoadValueCid(FlowGraphCompiler* compiler, 321 static void LoadValueCid(FlowGraphCompiler* compiler,
341 Register value_cid_reg, 322 Register value_cid_reg,
342 Register value_reg, 323 Register value_reg,
343 Label* value_is_smi = NULL) { 324 Label* value_is_smi = NULL) {
344 Label done; 325 Label done;
345 if (value_is_smi == NULL) { 326 if (value_is_smi == NULL) {
346 __ movl(value_cid_reg, Immediate(kSmiCid)); 327 __ movl(value_cid_reg, Immediate(kSmiCid));
347 } 328 }
348 __ testl(value_reg, Immediate(kSmiTagMask)); 329 __ testl(value_reg, Immediate(kSmiTagMask));
349 if (value_is_smi == NULL) { 330 if (value_is_smi == NULL) {
350 __ j(ZERO, &done, Assembler::kNearJump); 331 __ j(ZERO, &done, Assembler::kNearJump);
351 } else { 332 } else {
352 __ j(ZERO, value_is_smi); 333 __ j(ZERO, value_is_smi);
353 } 334 }
354 __ LoadClassId(value_cid_reg, value_reg); 335 __ LoadClassId(value_cid_reg, value_reg);
355 __ Bind(&done); 336 __ Bind(&done);
356 } 337 }
357 338
358
359 static Condition FlipCondition(Condition condition) { 339 static Condition FlipCondition(Condition condition) {
360 switch (condition) { 340 switch (condition) {
361 case EQUAL: 341 case EQUAL:
362 return EQUAL; 342 return EQUAL;
363 case NOT_EQUAL: 343 case NOT_EQUAL:
364 return NOT_EQUAL; 344 return NOT_EQUAL;
365 case LESS: 345 case LESS:
366 return GREATER; 346 return GREATER;
367 case LESS_EQUAL: 347 case LESS_EQUAL:
368 return GREATER_EQUAL; 348 return GREATER_EQUAL;
369 case GREATER: 349 case GREATER:
370 return LESS; 350 return LESS;
371 case GREATER_EQUAL: 351 case GREATER_EQUAL:
372 return LESS_EQUAL; 352 return LESS_EQUAL;
373 case BELOW: 353 case BELOW:
374 return ABOVE; 354 return ABOVE;
375 case BELOW_EQUAL: 355 case BELOW_EQUAL:
376 return ABOVE_EQUAL; 356 return ABOVE_EQUAL;
377 case ABOVE: 357 case ABOVE:
378 return BELOW; 358 return BELOW;
379 case ABOVE_EQUAL: 359 case ABOVE_EQUAL:
380 return BELOW_EQUAL; 360 return BELOW_EQUAL;
381 default: 361 default:
382 UNIMPLEMENTED(); 362 UNIMPLEMENTED();
383 return EQUAL; 363 return EQUAL;
384 } 364 }
385 } 365 }
386 366
387
388 static Condition NegateCondition(Condition condition) { 367 static Condition NegateCondition(Condition condition) {
389 switch (condition) { 368 switch (condition) {
390 case EQUAL: 369 case EQUAL:
391 return NOT_EQUAL; 370 return NOT_EQUAL;
392 case NOT_EQUAL: 371 case NOT_EQUAL:
393 return EQUAL; 372 return EQUAL;
394 case LESS: 373 case LESS:
395 return GREATER_EQUAL; 374 return GREATER_EQUAL;
396 case LESS_EQUAL: 375 case LESS_EQUAL:
397 return GREATER; 376 return GREATER;
(...skipping 12 matching lines...) Expand all
410 case PARITY_ODD: 389 case PARITY_ODD:
411 return PARITY_EVEN; 390 return PARITY_EVEN;
412 case PARITY_EVEN: 391 case PARITY_EVEN:
413 return PARITY_ODD; 392 return PARITY_ODD;
414 default: 393 default:
415 UNIMPLEMENTED(); 394 UNIMPLEMENTED();
416 return EQUAL; 395 return EQUAL;
417 } 396 }
418 } 397 }
419 398
420
421 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 399 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
422 Condition true_condition, 400 Condition true_condition,
423 BranchLabels labels) { 401 BranchLabels labels) {
424 if (labels.fall_through == labels.false_label) { 402 if (labels.fall_through == labels.false_label) {
425 // If the next block is the false successor, fall through to it. 403 // If the next block is the false successor, fall through to it.
426 __ j(true_condition, labels.true_label); 404 __ j(true_condition, labels.true_label);
427 } else { 405 } else {
428 // If the next block is not the false successor, branch to it. 406 // If the next block is not the false successor, branch to it.
429 Condition false_condition = NegateCondition(true_condition); 407 Condition false_condition = NegateCondition(true_condition);
430 __ j(false_condition, labels.false_label); 408 __ j(false_condition, labels.false_label);
431 409
432 // Fall through or jump to the true successor. 410 // Fall through or jump to the true successor.
433 if (labels.fall_through != labels.true_label) { 411 if (labels.fall_through != labels.true_label) {
434 __ jmp(labels.true_label); 412 __ jmp(labels.true_label);
435 } 413 }
436 } 414 }
437 } 415 }
438 416
439
440 static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler, 417 static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
441 const LocationSummary& locs, 418 const LocationSummary& locs,
442 Token::Kind kind, 419 Token::Kind kind,
443 BranchLabels labels) { 420 BranchLabels labels) {
444 Location left = locs.in(0); 421 Location left = locs.in(0);
445 Location right = locs.in(1); 422 Location right = locs.in(1);
446 ASSERT(!left.IsConstant() || !right.IsConstant()); 423 ASSERT(!left.IsConstant() || !right.IsConstant());
447 424
448 Condition true_condition = TokenKindToSmiCondition(kind); 425 Condition true_condition = TokenKindToSmiCondition(kind);
449 426
450 if (left.IsConstant()) { 427 if (left.IsConstant()) {
451 __ CompareObject(right.reg(), left.constant()); 428 __ CompareObject(right.reg(), left.constant());
452 true_condition = FlipCondition(true_condition); 429 true_condition = FlipCondition(true_condition);
453 } else if (right.IsConstant()) { 430 } else if (right.IsConstant()) {
454 __ CompareObject(left.reg(), right.constant()); 431 __ CompareObject(left.reg(), right.constant());
455 } else if (right.IsStackSlot()) { 432 } else if (right.IsStackSlot()) {
456 __ cmpl(left.reg(), right.ToStackSlotAddress()); 433 __ cmpl(left.reg(), right.ToStackSlotAddress());
457 } else { 434 } else {
458 __ cmpl(left.reg(), right.reg()); 435 __ cmpl(left.reg(), right.reg());
459 } 436 }
460 return true_condition; 437 return true_condition;
461 } 438 }
462 439
463
464 static Condition TokenKindToMintCondition(Token::Kind kind) { 440 static Condition TokenKindToMintCondition(Token::Kind kind) {
465 switch (kind) { 441 switch (kind) {
466 case Token::kEQ: 442 case Token::kEQ:
467 return EQUAL; 443 return EQUAL;
468 case Token::kNE: 444 case Token::kNE:
469 return NOT_EQUAL; 445 return NOT_EQUAL;
470 case Token::kLT: 446 case Token::kLT:
471 return LESS; 447 return LESS;
472 case Token::kGT: 448 case Token::kGT:
473 return GREATER; 449 return GREATER;
474 case Token::kLTE: 450 case Token::kLTE:
475 return LESS_EQUAL; 451 return LESS_EQUAL;
476 case Token::kGTE: 452 case Token::kGTE:
477 return GREATER_EQUAL; 453 return GREATER_EQUAL;
478 default: 454 default:
479 UNREACHABLE(); 455 UNREACHABLE();
480 return OVERFLOW; 456 return OVERFLOW;
481 } 457 }
482 } 458 }
483 459
484
485 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 460 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
486 const LocationSummary& locs, 461 const LocationSummary& locs,
487 Token::Kind kind, 462 Token::Kind kind,
488 BranchLabels labels) { 463 BranchLabels labels) {
489 ASSERT(Token::IsEqualityOperator(kind)); 464 ASSERT(Token::IsEqualityOperator(kind));
490 PairLocation* left_pair = locs.in(0).AsPairLocation(); 465 PairLocation* left_pair = locs.in(0).AsPairLocation();
491 Register left1 = left_pair->At(0).reg(); 466 Register left1 = left_pair->At(0).reg();
492 Register left2 = left_pair->At(1).reg(); 467 Register left2 = left_pair->At(1).reg();
493 PairLocation* right_pair = locs.in(1).AsPairLocation(); 468 PairLocation* right_pair = locs.in(1).AsPairLocation();
494 Register right1 = right_pair->At(0).reg(); 469 Register right1 = right_pair->At(0).reg();
495 Register right2 = right_pair->At(1).reg(); 470 Register right2 = right_pair->At(1).reg();
496 Label done; 471 Label done;
497 // Compare lower. 472 // Compare lower.
498 __ cmpl(left1, right1); 473 __ cmpl(left1, right1);
499 __ j(NOT_EQUAL, &done); 474 __ j(NOT_EQUAL, &done);
500 // Lower is equal, compare upper. 475 // Lower is equal, compare upper.
501 __ cmpl(left2, right2); 476 __ cmpl(left2, right2);
502 __ Bind(&done); 477 __ Bind(&done);
503 Condition true_condition = TokenKindToMintCondition(kind); 478 Condition true_condition = TokenKindToMintCondition(kind);
504 return true_condition; 479 return true_condition;
505 } 480 }
506 481
507
508 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, 482 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
509 const LocationSummary& locs, 483 const LocationSummary& locs,
510 Token::Kind kind, 484 Token::Kind kind,
511 BranchLabels labels) { 485 BranchLabels labels) {
512 PairLocation* left_pair = locs.in(0).AsPairLocation(); 486 PairLocation* left_pair = locs.in(0).AsPairLocation();
513 Register left1 = left_pair->At(0).reg(); 487 Register left1 = left_pair->At(0).reg();
514 Register left2 = left_pair->At(1).reg(); 488 Register left2 = left_pair->At(1).reg();
515 PairLocation* right_pair = locs.in(1).AsPairLocation(); 489 PairLocation* right_pair = locs.in(1).AsPairLocation();
516 Register right1 = right_pair->At(0).reg(); 490 Register right1 = right_pair->At(0).reg();
517 Register right2 = right_pair->At(1).reg(); 491 Register right2 = right_pair->At(1).reg();
(...skipping 23 matching lines...) Expand all
541 // Compare upper halves first. 515 // Compare upper halves first.
542 __ cmpl(left2, right2); 516 __ cmpl(left2, right2);
543 __ j(hi_cond, labels.true_label); 517 __ j(hi_cond, labels.true_label);
544 __ j(FlipCondition(hi_cond), labels.false_label); 518 __ j(FlipCondition(hi_cond), labels.false_label);
545 519
546 // If upper is equal, compare lower half. 520 // If upper is equal, compare lower half.
547 __ cmpl(left1, right1); 521 __ cmpl(left1, right1);
548 return lo_cond; 522 return lo_cond;
549 } 523 }
550 524
551
552 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 525 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
553 switch (kind) { 526 switch (kind) {
554 case Token::kEQ: 527 case Token::kEQ:
555 return EQUAL; 528 return EQUAL;
556 case Token::kNE: 529 case Token::kNE:
557 return NOT_EQUAL; 530 return NOT_EQUAL;
558 case Token::kLT: 531 case Token::kLT:
559 return BELOW; 532 return BELOW;
560 case Token::kGT: 533 case Token::kGT:
561 return ABOVE; 534 return ABOVE;
562 case Token::kLTE: 535 case Token::kLTE:
563 return BELOW_EQUAL; 536 return BELOW_EQUAL;
564 case Token::kGTE: 537 case Token::kGTE:
565 return ABOVE_EQUAL; 538 return ABOVE_EQUAL;
566 default: 539 default:
567 UNREACHABLE(); 540 UNREACHABLE();
568 return OVERFLOW; 541 return OVERFLOW;
569 } 542 }
570 } 543 }
571 544
572
573 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 545 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
574 const LocationSummary& locs, 546 const LocationSummary& locs,
575 Token::Kind kind, 547 Token::Kind kind,
576 BranchLabels labels) { 548 BranchLabels labels) {
577 XmmRegister left = locs.in(0).fpu_reg(); 549 XmmRegister left = locs.in(0).fpu_reg();
578 XmmRegister right = locs.in(1).fpu_reg(); 550 XmmRegister right = locs.in(1).fpu_reg();
579 551
580 __ comisd(left, right); 552 __ comisd(left, right);
581 553
582 Condition true_condition = TokenKindToDoubleCondition(kind); 554 Condition true_condition = TokenKindToDoubleCondition(kind);
583 Label* nan_result = 555 Label* nan_result =
584 (true_condition == NOT_EQUAL) ? labels.true_label : labels.false_label; 556 (true_condition == NOT_EQUAL) ? labels.true_label : labels.false_label;
585 __ j(PARITY_EVEN, nan_result); 557 __ j(PARITY_EVEN, nan_result);
586 return true_condition; 558 return true_condition;
587 } 559 }
588 560
589
590 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 561 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
591 BranchLabels labels) { 562 BranchLabels labels) {
592 if (operation_cid() == kSmiCid) { 563 if (operation_cid() == kSmiCid) {
593 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 564 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
594 } else if (operation_cid() == kMintCid) { 565 } else if (operation_cid() == kMintCid) {
595 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels); 566 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
596 } else { 567 } else {
597 ASSERT(operation_cid() == kDoubleCid); 568 ASSERT(operation_cid() == kDoubleCid);
598 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 569 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
599 } 570 }
600 } 571 }
601 572
602
603 void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 573 void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
604 Label is_true, is_false; 574 Label is_true, is_false;
605 BranchLabels labels = {&is_true, &is_false, &is_false}; 575 BranchLabels labels = {&is_true, &is_false, &is_false};
606 Condition true_condition = EmitComparisonCode(compiler, labels); 576 Condition true_condition = EmitComparisonCode(compiler, labels);
607 if (true_condition != INVALID_CONDITION) { 577 if (true_condition != INVALID_CONDITION) {
608 EmitBranchOnCondition(compiler, true_condition, labels); 578 EmitBranchOnCondition(compiler, true_condition, labels);
609 } 579 }
610 580
611 Register result = locs()->out(0).reg(); 581 Register result = locs()->out(0).reg();
612 Label done; 582 Label done;
613 __ Bind(&is_false); 583 __ Bind(&is_false);
614 __ LoadObject(result, Bool::False()); 584 __ LoadObject(result, Bool::False());
615 __ jmp(&done, Assembler::kNearJump); 585 __ jmp(&done, Assembler::kNearJump);
616 __ Bind(&is_true); 586 __ Bind(&is_true);
617 __ LoadObject(result, Bool::True()); 587 __ LoadObject(result, Bool::True());
618 __ Bind(&done); 588 __ Bind(&done);
619 } 589 }
620 590
621
622 void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 591 void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
623 BranchInstr* branch) { 592 BranchInstr* branch) {
624 BranchLabels labels = compiler->CreateBranchLabels(branch); 593 BranchLabels labels = compiler->CreateBranchLabels(branch);
625 Condition true_condition = EmitComparisonCode(compiler, labels); 594 Condition true_condition = EmitComparisonCode(compiler, labels);
626 if (true_condition != INVALID_CONDITION) { 595 if (true_condition != INVALID_CONDITION) {
627 EmitBranchOnCondition(compiler, true_condition, labels); 596 EmitBranchOnCondition(compiler, true_condition, labels);
628 } 597 }
629 } 598 }
630 599
631
632 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { 600 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
633 const intptr_t kNumInputs = 2; 601 const intptr_t kNumInputs = 2;
634 const intptr_t kNumTemps = 0; 602 const intptr_t kNumTemps = 0;
635 LocationSummary* locs = new (zone) 603 LocationSummary* locs = new (zone)
636 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 604 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
637 locs->set_in(0, Location::RequiresRegister()); 605 locs->set_in(0, Location::RequiresRegister());
638 // Only one input can be a constant operand. The case of two constant 606 // Only one input can be a constant operand. The case of two constant
639 // operands should be handled by constant propagation. 607 // operands should be handled by constant propagation.
640 locs->set_in(1, Location::RegisterOrConstant(right())); 608 locs->set_in(1, Location::RegisterOrConstant(right()));
641 return locs; 609 return locs;
642 } 610 }
643 611
644
645 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 612 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
646 BranchLabels labels) { 613 BranchLabels labels) {
647 Register left = locs()->in(0).reg(); 614 Register left = locs()->in(0).reg();
648 Location right = locs()->in(1); 615 Location right = locs()->in(1);
649 if (right.IsConstant()) { 616 if (right.IsConstant()) {
650 ASSERT(right.constant().IsSmi()); 617 ASSERT(right.constant().IsSmi());
651 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); 618 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
652 __ testl(left, Immediate(imm)); 619 __ testl(left, Immediate(imm));
653 } else { 620 } else {
654 __ testl(left, right.reg()); 621 __ testl(left, right.reg());
655 } 622 }
656 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; 623 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
657 return true_condition; 624 return true_condition;
658 } 625 }
659 626
660
661 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 627 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
662 bool opt) const { 628 bool opt) const {
663 const intptr_t kNumInputs = 1; 629 const intptr_t kNumInputs = 1;
664 const intptr_t kNumTemps = 1; 630 const intptr_t kNumTemps = 1;
665 LocationSummary* locs = new (zone) 631 LocationSummary* locs = new (zone)
666 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 632 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
667 locs->set_in(0, Location::RequiresRegister()); 633 locs->set_in(0, Location::RequiresRegister());
668 locs->set_temp(0, Location::RequiresRegister()); 634 locs->set_temp(0, Location::RequiresRegister());
669 locs->set_out(0, Location::RequiresRegister()); 635 locs->set_out(0, Location::RequiresRegister());
670 return locs; 636 return locs;
671 } 637 }
672 638
673
674 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 639 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
675 BranchLabels labels) { 640 BranchLabels labels) {
676 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); 641 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
677 Register val_reg = locs()->in(0).reg(); 642 Register val_reg = locs()->in(0).reg();
678 Register cid_reg = locs()->temp(0).reg(); 643 Register cid_reg = locs()->temp(0).reg();
679 644
680 Label* deopt = 645 Label* deopt = CanDeoptimize() ? compiler->AddDeoptStub(
681 CanDeoptimize() 646 deopt_id(), ICData::kDeoptTestCids,
682 ? compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids, 647 licm_hoisted_ ? ICData::kHoisted : 0)
683 licm_hoisted_ ? ICData::kHoisted : 0) 648 : NULL;
684 : NULL;
685 649
686 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; 650 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
687 const ZoneGrowableArray<intptr_t>& data = cid_results(); 651 const ZoneGrowableArray<intptr_t>& data = cid_results();
688 ASSERT(data[0] == kSmiCid); 652 ASSERT(data[0] == kSmiCid);
689 bool result = data[1] == true_result; 653 bool result = data[1] == true_result;
690 __ testl(val_reg, Immediate(kSmiTagMask)); 654 __ testl(val_reg, Immediate(kSmiTagMask));
691 __ j(ZERO, result ? labels.true_label : labels.false_label); 655 __ j(ZERO, result ? labels.true_label : labels.false_label);
692 __ LoadClassId(cid_reg, val_reg); 656 __ LoadClassId(cid_reg, val_reg);
693 for (intptr_t i = 2; i < data.length(); i += 2) { 657 for (intptr_t i = 2; i < data.length(); i += 2) {
694 const intptr_t test_cid = data[i]; 658 const intptr_t test_cid = data[i];
(...skipping 12 matching lines...) Expand all
707 __ jmp(target); 671 __ jmp(target);
708 } 672 }
709 } else { 673 } else {
710 __ jmp(deopt); 674 __ jmp(deopt);
711 } 675 }
712 // Dummy result as this method already did the jump, there's no need 676 // Dummy result as this method already did the jump, there's no need
713 // for the caller to branch on a condition. 677 // for the caller to branch on a condition.
714 return INVALID_CONDITION; 678 return INVALID_CONDITION;
715 } 679 }
716 680
717
718 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 681 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
719 bool opt) const { 682 bool opt) const {
720 const intptr_t kNumInputs = 2; 683 const intptr_t kNumInputs = 2;
721 const intptr_t kNumTemps = 0; 684 const intptr_t kNumTemps = 0;
722 if (operation_cid() == kMintCid) { 685 if (operation_cid() == kMintCid) {
723 const intptr_t kNumTemps = 0; 686 const intptr_t kNumTemps = 0;
724 LocationSummary* locs = new (zone) 687 LocationSummary* locs = new (zone)
725 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 688 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
726 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 689 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
727 Location::RequiresRegister())); 690 Location::RequiresRegister()));
(...skipping 16 matching lines...) Expand all
744 summary->set_in(0, Location::RegisterOrConstant(left())); 707 summary->set_in(0, Location::RegisterOrConstant(left()));
745 // Only one input can be a constant operand. The case of two constant 708 // Only one input can be a constant operand. The case of two constant
746 // operands should be handled by constant propagation. 709 // operands should be handled by constant propagation.
747 summary->set_in(1, summary->in(0).IsConstant() 710 summary->set_in(1, summary->in(0).IsConstant()
748 ? Location::RequiresRegister() 711 ? Location::RequiresRegister()
749 : Location::RegisterOrConstant(right())); 712 : Location::RegisterOrConstant(right()));
750 summary->set_out(0, Location::RequiresRegister()); 713 summary->set_out(0, Location::RequiresRegister());
751 return summary; 714 return summary;
752 } 715 }
753 716
754
755 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 717 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
756 BranchLabels labels) { 718 BranchLabels labels) {
757 if (operation_cid() == kSmiCid) { 719 if (operation_cid() == kSmiCid) {
758 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 720 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
759 } else if (operation_cid() == kMintCid) { 721 } else if (operation_cid() == kMintCid) {
760 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); 722 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
761 } else { 723 } else {
762 ASSERT(operation_cid() == kDoubleCid); 724 ASSERT(operation_cid() == kDoubleCid);
763 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 725 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
764 } 726 }
765 } 727 }
766 728
767
768 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, 729 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
769 bool opt) const { 730 bool opt) const {
770 return MakeCallSummary(zone); 731 return MakeCallSummary(zone);
771 } 732 }
772 733
773
774 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 734 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
775 SetupNative(); 735 SetupNative();
776 Register result = locs()->out(0).reg(); 736 Register result = locs()->out(0).reg();
777 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); 737 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
778 738
779 // Push the result place holder initialized to NULL. 739 // Push the result place holder initialized to NULL.
780 __ PushObject(Object::null_object()); 740 __ PushObject(Object::null_object());
781 // Pass a pointer to the first argument in EAX. 741 // Pass a pointer to the first argument in EAX.
782 if (!function().HasOptionalParameters()) { 742 if (!function().HasOptionalParameters()) {
783 __ leal(EAX, 743 __ leal(EAX,
(...skipping 16 matching lines...) Expand all
800 stub_entry = StubCode::CallNoScopeNative_entry(); 760 stub_entry = StubCode::CallNoScopeNative_entry();
801 } 761 }
802 const ExternalLabel label(reinterpret_cast<uword>(native_c_function())); 762 const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
803 __ movl(ECX, Immediate(label.address())); 763 __ movl(ECX, Immediate(label.address()));
804 compiler->GenerateCall(token_pos(), *stub_entry, RawPcDescriptors::kOther, 764 compiler->GenerateCall(token_pos(), *stub_entry, RawPcDescriptors::kOther,
805 locs()); 765 locs());
806 766
807 __ popl(result); 767 __ popl(result);
808 } 768 }
809 769
810
811 static bool CanBeImmediateIndex(Value* value, intptr_t cid) { 770 static bool CanBeImmediateIndex(Value* value, intptr_t cid) {
812 ConstantInstr* constant = value->definition()->AsConstant(); 771 ConstantInstr* constant = value->definition()->AsConstant();
813 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) { 772 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) {
814 return false; 773 return false;
815 } 774 }
816 const int64_t index = Smi::Cast(constant->value()).AsInt64Value(); 775 const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
817 const intptr_t scale = Instance::ElementSizeFor(cid); 776 const intptr_t scale = Instance::ElementSizeFor(cid);
818 const intptr_t offset = Instance::DataOffsetFor(cid); 777 const intptr_t offset = Instance::DataOffsetFor(cid);
819 const int64_t displacement = index * scale + offset; 778 const int64_t displacement = index * scale + offset;
820 return Utils::IsInt(32, displacement); 779 return Utils::IsInt(32, displacement);
821 } 780 }
822 781
823
824 LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary( 782 LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
825 Zone* zone, 783 Zone* zone,
826 bool opt) const { 784 bool opt) const {
827 const intptr_t kNumInputs = 1; 785 const intptr_t kNumInputs = 1;
828 // TODO(fschneider): Allow immediate operands for the char code. 786 // TODO(fschneider): Allow immediate operands for the char code.
829 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(), 787 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
830 LocationSummary::kNoCall); 788 LocationSummary::kNoCall);
831 } 789 }
832 790
833
834 void OneByteStringFromCharCodeInstr::EmitNativeCode( 791 void OneByteStringFromCharCodeInstr::EmitNativeCode(
835 FlowGraphCompiler* compiler) { 792 FlowGraphCompiler* compiler) {
836 Register char_code = locs()->in(0).reg(); 793 Register char_code = locs()->in(0).reg();
837 Register result = locs()->out(0).reg(); 794 Register result = locs()->out(0).reg();
838 __ movl(result, 795 __ movl(result,
839 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); 796 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
840 __ movl(result, Address(result, char_code, 797 __ movl(result, Address(result, char_code,
841 TIMES_HALF_WORD_SIZE, // Char code is a smi. 798 TIMES_HALF_WORD_SIZE, // Char code is a smi.
842 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 799 Symbols::kNullCharCodeSymbolOffset * kWordSize));
843 } 800 }
844 801
845
846 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Zone* zone, 802 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(Zone* zone,
847 bool opt) const { 803 bool opt) const {
848 const intptr_t kNumInputs = 1; 804 const intptr_t kNumInputs = 1;
849 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(), 805 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
850 LocationSummary::kNoCall); 806 LocationSummary::kNoCall);
851 } 807 }
852 808
853
854 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 809 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
855 ASSERT(cid_ == kOneByteStringCid); 810 ASSERT(cid_ == kOneByteStringCid);
856 Register str = locs()->in(0).reg(); 811 Register str = locs()->in(0).reg();
857 Register result = locs()->out(0).reg(); 812 Register result = locs()->out(0).reg();
858 Label is_one, done; 813 Label is_one, done;
859 __ movl(result, FieldAddress(str, String::length_offset())); 814 __ movl(result, FieldAddress(str, String::length_offset()));
860 __ cmpl(result, Immediate(Smi::RawValue(1))); 815 __ cmpl(result, Immediate(Smi::RawValue(1)));
861 __ j(EQUAL, &is_one, Assembler::kNearJump); 816 __ j(EQUAL, &is_one, Assembler::kNearJump);
862 __ movl(result, Immediate(Smi::RawValue(-1))); 817 __ movl(result, Immediate(Smi::RawValue(-1)));
863 __ jmp(&done); 818 __ jmp(&done);
864 __ Bind(&is_one); 819 __ Bind(&is_one);
865 __ movzxb(result, FieldAddress(str, OneByteString::data_offset())); 820 __ movzxb(result, FieldAddress(str, OneByteString::data_offset()));
866 __ SmiTag(result); 821 __ SmiTag(result);
867 __ Bind(&done); 822 __ Bind(&done);
868 } 823 }
869 824
870
871 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Zone* zone, 825 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Zone* zone,
872 bool opt) const { 826 bool opt) const {
873 const intptr_t kNumInputs = 1; 827 const intptr_t kNumInputs = 1;
874 const intptr_t kNumTemps = 0; 828 const intptr_t kNumTemps = 0;
875 LocationSummary* summary = new (zone) 829 LocationSummary* summary = new (zone)
876 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 830 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
877 summary->set_in(0, Location::RegisterLocation(EAX)); 831 summary->set_in(0, Location::RegisterLocation(EAX));
878 summary->set_out(0, Location::RegisterLocation(EAX)); 832 summary->set_out(0, Location::RegisterLocation(EAX));
879 return summary; 833 return summary;
880 } 834 }
881 835
882
883 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 836 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
884 Register array = locs()->in(0).reg(); 837 Register array = locs()->in(0).reg();
885 __ pushl(array); 838 __ pushl(array);
886 const int kTypeArgsLen = 0; 839 const int kTypeArgsLen = 0;
887 const int kNumberOfArguments = 1; 840 const int kNumberOfArguments = 1;
888 const Array& kNoArgumentNames = Object::null_array(); 841 const Array& kNoArgumentNames = Object::null_array();
889 ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames); 842 ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
890 compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(), 843 compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(),
891 args_info, locs(), ICData::Handle()); 844 args_info, locs(), ICData::Handle());
892 ASSERT(locs()->out(0).reg() == EAX); 845 ASSERT(locs()->out(0).reg() == EAX);
893 } 846 }
894 847
895
896 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(Zone* zone, 848 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(Zone* zone,
897 bool opt) const { 849 bool opt) const {
898 const intptr_t kNumInputs = 1; 850 const intptr_t kNumInputs = 1;
899 return LocationSummary::Make(zone, kNumInputs, Location::SameAsFirstInput(), 851 return LocationSummary::Make(zone, kNumInputs, Location::SameAsFirstInput(),
900 LocationSummary::kNoCall); 852 LocationSummary::kNoCall);
901 } 853 }
902 854
903
904 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 855 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
905 Register obj = locs()->in(0).reg(); 856 Register obj = locs()->in(0).reg();
906 Register result = locs()->out(0).reg(); 857 Register result = locs()->out(0).reg();
907 if (object()->definition()->representation() == kUntagged) { 858 if (object()->definition()->representation() == kUntagged) {
908 __ movl(result, Address(obj, offset())); 859 __ movl(result, Address(obj, offset()));
909 } else { 860 } else {
910 ASSERT(object()->definition()->representation() == kTagged); 861 ASSERT(object()->definition()->representation() == kTagged);
911 __ movl(result, FieldAddress(obj, offset())); 862 __ movl(result, FieldAddress(obj, offset()));
912 } 863 }
913 } 864 }
914 865
915
916 LocationSummary* LoadClassIdInstr::MakeLocationSummary(Zone* zone, 866 LocationSummary* LoadClassIdInstr::MakeLocationSummary(Zone* zone,
917 bool opt) const { 867 bool opt) const {
918 const intptr_t kNumInputs = 1; 868 const intptr_t kNumInputs = 1;
919 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(), 869 return LocationSummary::Make(zone, kNumInputs, Location::RequiresRegister(),
920 LocationSummary::kNoCall); 870 LocationSummary::kNoCall);
921 } 871 }
922 872
923
924 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 873 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
925 const Register object = locs()->in(0).reg(); 874 const Register object = locs()->in(0).reg();
926 const Register result = locs()->out(0).reg(); 875 const Register result = locs()->out(0).reg();
927 const AbstractType& value_type = *this->object()->Type()->ToAbstractType(); 876 const AbstractType& value_type = *this->object()->Type()->ToAbstractType();
928 if (CompileType::Smi().IsAssignableTo(value_type) || 877 if (CompileType::Smi().IsAssignableTo(value_type) ||
929 value_type.IsTypeParameter()) { 878 value_type.IsTypeParameter()) {
930 // We don't use Assembler::LoadTaggedClassIdMayBeSmi() here---which uses 879 // We don't use Assembler::LoadTaggedClassIdMayBeSmi() here---which uses
931 // a conditional move instead, and requires an additional register---because 880 // a conditional move instead, and requires an additional register---because
932 // it is slower, probably due to branch prediction usually working just fine 881 // it is slower, probably due to branch prediction usually working just fine
933 // in this case. 882 // in this case.
934 ASSERT(result != object); 883 ASSERT(result != object);
935 Label done; 884 Label done;
936 __ movl(result, Immediate(kSmiCid << 1)); 885 __ movl(result, Immediate(kSmiCid << 1));
937 __ testl(object, Immediate(kSmiTagMask)); 886 __ testl(object, Immediate(kSmiTagMask));
938 __ j(EQUAL, &done, Assembler::kNearJump); 887 __ j(EQUAL, &done, Assembler::kNearJump);
939 __ LoadClassId(result, object); 888 __ LoadClassId(result, object);
940 __ SmiTag(result); 889 __ SmiTag(result);
941 __ Bind(&done); 890 __ Bind(&done);
942 } else { 891 } else {
943 __ LoadClassId(result, object); 892 __ LoadClassId(result, object);
944 __ SmiTag(result); 893 __ SmiTag(result);
945 } 894 }
946 } 895 }
947 896
948
949 CompileType LoadIndexedInstr::ComputeType() const { 897 CompileType LoadIndexedInstr::ComputeType() const {
950 switch (class_id_) { 898 switch (class_id_) {
951 case kArrayCid: 899 case kArrayCid:
952 case kImmutableArrayCid: 900 case kImmutableArrayCid:
953 return CompileType::Dynamic(); 901 return CompileType::Dynamic();
954 902
955 case kTypedDataFloat32ArrayCid: 903 case kTypedDataFloat32ArrayCid:
956 case kTypedDataFloat64ArrayCid: 904 case kTypedDataFloat64ArrayCid:
957 return CompileType::FromCid(kDoubleCid); 905 return CompileType::FromCid(kDoubleCid);
958 case kTypedDataFloat32x4ArrayCid: 906 case kTypedDataFloat32x4ArrayCid:
(...skipping 19 matching lines...) Expand all
978 case kTypedDataInt32ArrayCid: 926 case kTypedDataInt32ArrayCid:
979 case kTypedDataUint32ArrayCid: 927 case kTypedDataUint32ArrayCid:
980 return CompileType::Int(); 928 return CompileType::Int();
981 929
982 default: 930 default:
983 UNIMPLEMENTED(); 931 UNIMPLEMENTED();
984 return CompileType::Dynamic(); 932 return CompileType::Dynamic();
985 } 933 }
986 } 934 }
987 935
988
989 Representation LoadIndexedInstr::representation() const { 936 Representation LoadIndexedInstr::representation() const {
990 switch (class_id_) { 937 switch (class_id_) {
991 case kArrayCid: 938 case kArrayCid:
992 case kImmutableArrayCid: 939 case kImmutableArrayCid:
993 case kTypedDataInt8ArrayCid: 940 case kTypedDataInt8ArrayCid:
994 case kTypedDataUint8ArrayCid: 941 case kTypedDataUint8ArrayCid:
995 case kTypedDataUint8ClampedArrayCid: 942 case kTypedDataUint8ClampedArrayCid:
996 case kExternalTypedDataUint8ArrayCid: 943 case kExternalTypedDataUint8ArrayCid:
997 case kExternalTypedDataUint8ClampedArrayCid: 944 case kExternalTypedDataUint8ClampedArrayCid:
998 case kTypedDataInt16ArrayCid: 945 case kTypedDataInt16ArrayCid:
(...skipping 15 matching lines...) Expand all
1014 case kTypedDataInt32x4ArrayCid: 961 case kTypedDataInt32x4ArrayCid:
1015 return kUnboxedInt32x4; 962 return kUnboxedInt32x4;
1016 case kTypedDataFloat64x2ArrayCid: 963 case kTypedDataFloat64x2ArrayCid:
1017 return kUnboxedFloat64x2; 964 return kUnboxedFloat64x2;
1018 default: 965 default:
1019 UNIMPLEMENTED(); 966 UNIMPLEMENTED();
1020 return kTagged; 967 return kTagged;
1021 } 968 }
1022 } 969 }
1023 970
1024
1025 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, 971 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
1026 bool opt) const { 972 bool opt) const {
1027 const intptr_t kNumInputs = 2; 973 const intptr_t kNumInputs = 2;
1028 const intptr_t kNumTemps = 0; 974 const intptr_t kNumTemps = 0;
1029 LocationSummary* locs = new (zone) 975 LocationSummary* locs = new (zone)
1030 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 976 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1031 locs->set_in(0, Location::RequiresRegister()); 977 locs->set_in(0, Location::RequiresRegister());
1032 if (CanBeImmediateIndex(index(), class_id())) { 978 if (CanBeImmediateIndex(index(), class_id())) {
1033 // CanBeImmediateIndex must return false for unsafe smis. 979 // CanBeImmediateIndex must return false for unsafe smis.
1034 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 980 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
(...skipping 14 matching lines...) Expand all
1049 } else if (representation() == kUnboxedInt32) { 995 } else if (representation() == kUnboxedInt32) {
1050 ASSERT(class_id() == kTypedDataInt32ArrayCid); 996 ASSERT(class_id() == kTypedDataInt32ArrayCid);
1051 locs->set_out(0, Location::RequiresRegister()); 997 locs->set_out(0, Location::RequiresRegister());
1052 } else { 998 } else {
1053 ASSERT(representation() == kTagged); 999 ASSERT(representation() == kTagged);
1054 locs->set_out(0, Location::RequiresRegister()); 1000 locs->set_out(0, Location::RequiresRegister());
1055 } 1001 }
1056 return locs; 1002 return locs;
1057 } 1003 }
1058 1004
1059
1060 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1005 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1061 // The array register points to the backing store for external arrays. 1006 // The array register points to the backing store for external arrays.
1062 const Register array = locs()->in(0).reg(); 1007 const Register array = locs()->in(0).reg();
1063 const Location index = locs()->in(1); 1008 const Location index = locs()->in(1);
1064 1009
1065 Address element_address = 1010 Address element_address =
1066 index.IsRegister() 1011 index.IsRegister()
1067 ? Assembler::ElementAddressForRegIndex( 1012 ? Assembler::ElementAddressForRegIndex(
1068 IsExternal(), class_id(), index_scale(), array, index.reg()) 1013 IsExternal(), class_id(), index_scale(), array, index.reg())
1069 : Assembler::ElementAddressForIntIndex( 1014 : Assembler::ElementAddressForIntIndex(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 __ movzxw(result, element_address); 1094 __ movzxw(result, element_address);
1150 __ SmiTag(result); 1095 __ SmiTag(result);
1151 break; 1096 break;
1152 default: 1097 default:
1153 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1098 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1154 __ movl(result, element_address); 1099 __ movl(result, element_address);
1155 break; 1100 break;
1156 } 1101 }
1157 } 1102 }
1158 1103
1159
1160 Representation StoreIndexedInstr::RequiredInputRepresentation( 1104 Representation StoreIndexedInstr::RequiredInputRepresentation(
1161 intptr_t idx) const { 1105 intptr_t idx) const {
1162 // Array can be a Dart object or a pointer to external data. 1106 // Array can be a Dart object or a pointer to external data.
1163 if (idx == 0) return kNoRepresentation; // Flexible input representation. 1107 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1164 if (idx == 1) return kTagged; // Index is a smi. 1108 if (idx == 1) return kTagged; // Index is a smi.
1165 ASSERT(idx == 2); 1109 ASSERT(idx == 2);
1166 switch (class_id_) { 1110 switch (class_id_) {
1167 case kArrayCid: 1111 case kArrayCid:
1168 case kOneByteStringCid: 1112 case kOneByteStringCid:
1169 case kTypedDataInt8ArrayCid: 1113 case kTypedDataInt8ArrayCid:
(...skipping 16 matching lines...) Expand all
1186 case kTypedDataInt32x4ArrayCid: 1130 case kTypedDataInt32x4ArrayCid:
1187 return kUnboxedInt32x4; 1131 return kUnboxedInt32x4;
1188 case kTypedDataFloat64x2ArrayCid: 1132 case kTypedDataFloat64x2ArrayCid:
1189 return kUnboxedFloat64x2; 1133 return kUnboxedFloat64x2;
1190 default: 1134 default:
1191 UNIMPLEMENTED(); 1135 UNIMPLEMENTED();
1192 return kTagged; 1136 return kTagged;
1193 } 1137 }
1194 } 1138 }
1195 1139
1196
1197 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, 1140 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
1198 bool opt) const { 1141 bool opt) const {
1199 const intptr_t kNumInputs = 3; 1142 const intptr_t kNumInputs = 3;
1200 const intptr_t kNumTemps = 0; 1143 const intptr_t kNumTemps = 0;
1201 LocationSummary* locs = new (zone) 1144 LocationSummary* locs = new (zone)
1202 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1145 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1203 locs->set_in(0, Location::RequiresRegister()); 1146 locs->set_in(0, Location::RequiresRegister());
1204 if (CanBeImmediateIndex(index(), class_id())) { 1147 if (CanBeImmediateIndex(index(), class_id())) {
1205 // CanBeImmediateIndex must return false for unsafe smis. 1148 // CanBeImmediateIndex must return false for unsafe smis.
1206 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1149 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 case kTypedDataFloat64x2ArrayCid: 1188 case kTypedDataFloat64x2ArrayCid:
1246 locs->set_in(2, Location::RequiresFpuRegister()); 1189 locs->set_in(2, Location::RequiresFpuRegister());
1247 break; 1190 break;
1248 default: 1191 default:
1249 UNREACHABLE(); 1192 UNREACHABLE();
1250 return NULL; 1193 return NULL;
1251 } 1194 }
1252 return locs; 1195 return locs;
1253 } 1196 }
1254 1197
1255
1256 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1198 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1257 // The array register points to the backing store for external arrays. 1199 // The array register points to the backing store for external arrays.
1258 const Register array = locs()->in(0).reg(); 1200 const Register array = locs()->in(0).reg();
1259 const Location index = locs()->in(1); 1201 const Location index = locs()->in(1);
1260 1202
1261 Address element_address = 1203 Address element_address =
1262 index.IsRegister() 1204 index.IsRegister()
1263 ? Assembler::ElementAddressForRegIndex( 1205 ? Assembler::ElementAddressForRegIndex(
1264 IsExternal(), class_id(), index_scale(), array, index.reg()) 1206 IsExternal(), class_id(), index_scale(), array, index.reg())
1265 : Assembler::ElementAddressForIntIndex( 1207 : Assembler::ElementAddressForIntIndex(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 case kTypedDataInt32x4ArrayCid: 1287 case kTypedDataInt32x4ArrayCid:
1346 case kTypedDataFloat32x4ArrayCid: 1288 case kTypedDataFloat32x4ArrayCid:
1347 case kTypedDataFloat64x2ArrayCid: 1289 case kTypedDataFloat64x2ArrayCid:
1348 __ movups(element_address, locs()->in(2).fpu_reg()); 1290 __ movups(element_address, locs()->in(2).fpu_reg());
1349 break; 1291 break;
1350 default: 1292 default:
1351 UNREACHABLE(); 1293 UNREACHABLE();
1352 } 1294 }
1353 } 1295 }
1354 1296
1355
1356 LocationSummary* GuardFieldClassInstr::MakeLocationSummary(Zone* zone, 1297 LocationSummary* GuardFieldClassInstr::MakeLocationSummary(Zone* zone,
1357 bool opt) const { 1298 bool opt) const {
1358 const intptr_t kNumInputs = 1; 1299 const intptr_t kNumInputs = 1;
1359 1300
1360 const intptr_t value_cid = value()->Type()->ToCid(); 1301 const intptr_t value_cid = value()->Type()->ToCid();
1361 const intptr_t field_cid = field().guarded_cid(); 1302 const intptr_t field_cid = field().guarded_cid();
1362 1303
1363 const bool emit_full_guard = !opt || (field_cid == kIllegalCid); 1304 const bool emit_full_guard = !opt || (field_cid == kIllegalCid);
1364 const bool needs_value_cid_temp_reg = 1305 const bool needs_value_cid_temp_reg =
1365 (value_cid == kDynamicCid) && (emit_full_guard || (field_cid != kSmiCid)); 1306 (value_cid == kDynamicCid) && (emit_full_guard || (field_cid != kSmiCid));
(...skipping 11 matching lines...) Expand all
1377 LocationSummary(zone, kNumInputs, num_temps, LocationSummary::kNoCall); 1318 LocationSummary(zone, kNumInputs, num_temps, LocationSummary::kNoCall);
1378 summary->set_in(0, Location::RequiresRegister()); 1319 summary->set_in(0, Location::RequiresRegister());
1379 1320
1380 for (intptr_t i = 0; i < num_temps; i++) { 1321 for (intptr_t i = 0; i < num_temps; i++) {
1381 summary->set_temp(i, Location::RequiresRegister()); 1322 summary->set_temp(i, Location::RequiresRegister());
1382 } 1323 }
1383 1324
1384 return summary; 1325 return summary;
1385 } 1326 }
1386 1327
1387
1388 void GuardFieldClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1328 void GuardFieldClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1389 ASSERT(sizeof(classid_t) == kInt16Size); 1329 ASSERT(sizeof(classid_t) == kInt16Size);
1390 const intptr_t value_cid = value()->Type()->ToCid(); 1330 const intptr_t value_cid = value()->Type()->ToCid();
1391 const intptr_t field_cid = field().guarded_cid(); 1331 const intptr_t field_cid = field().guarded_cid();
1392 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid; 1332 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
1393 1333
1394 if (field_cid == kDynamicCid) { 1334 if (field_cid == kDynamicCid) {
1395 if (Compiler::IsBackgroundCompilation()) { 1335 if (Compiler::IsBackgroundCompilation()) {
1396 // Field state changed while compiling. 1336 // Field state changed while compiling.
1397 Compiler::AbortBackgroundCompilation( 1337 Compiler::AbortBackgroundCompilation(
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 __ j(NOT_EQUAL, fail); 1463 __ j(NOT_EQUAL, fail);
1524 } else { 1464 } else {
1525 // Both value's and field's class id is known. 1465 // Both value's and field's class id is known.
1526 ASSERT((value_cid != field_cid) && (value_cid != nullability)); 1466 ASSERT((value_cid != field_cid) && (value_cid != nullability));
1527 __ jmp(fail); 1467 __ jmp(fail);
1528 } 1468 }
1529 } 1469 }
1530 __ Bind(&ok); 1470 __ Bind(&ok);
1531 } 1471 }
1532 1472
1533
1534 LocationSummary* GuardFieldLengthInstr::MakeLocationSummary(Zone* zone, 1473 LocationSummary* GuardFieldLengthInstr::MakeLocationSummary(Zone* zone,
1535 bool opt) const { 1474 bool opt) const {
1536 const intptr_t kNumInputs = 1; 1475 const intptr_t kNumInputs = 1;
1537 if (!opt || (field().guarded_list_length() == Field::kUnknownFixedLength)) { 1476 if (!opt || (field().guarded_list_length() == Field::kUnknownFixedLength)) {
1538 const intptr_t kNumTemps = 3; 1477 const intptr_t kNumTemps = 3;
1539 LocationSummary* summary = new (zone) 1478 LocationSummary* summary = new (zone)
1540 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1479 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1541 summary->set_in(0, Location::RequiresRegister()); 1480 summary->set_in(0, Location::RequiresRegister());
1542 // We need temporaries for field object, length offset and expected length. 1481 // We need temporaries for field object, length offset and expected length.
1543 summary->set_temp(0, Location::RequiresRegister()); 1482 summary->set_temp(0, Location::RequiresRegister());
1544 summary->set_temp(1, Location::RequiresRegister()); 1483 summary->set_temp(1, Location::RequiresRegister());
1545 summary->set_temp(2, Location::RequiresRegister()); 1484 summary->set_temp(2, Location::RequiresRegister());
1546 return summary; 1485 return summary;
1547 } else { 1486 } else {
1548 LocationSummary* summary = new (zone) 1487 LocationSummary* summary = new (zone)
1549 LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall); 1488 LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall);
1550 summary->set_in(0, Location::RequiresRegister()); 1489 summary->set_in(0, Location::RequiresRegister());
1551 return summary; 1490 return summary;
1552 } 1491 }
1553 UNREACHABLE(); 1492 UNREACHABLE();
1554 } 1493 }
1555 1494
1556
1557 void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1495 void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1558 if (field().guarded_list_length() == Field::kNoFixedLength) { 1496 if (field().guarded_list_length() == Field::kNoFixedLength) {
1559 if (Compiler::IsBackgroundCompilation()) { 1497 if (Compiler::IsBackgroundCompilation()) {
1560 // Field state changed while compiling. 1498 // Field state changed while compiling.
1561 Compiler::AbortBackgroundCompilation( 1499 Compiler::AbortBackgroundCompilation(
1562 deopt_id(), 1500 deopt_id(),
1563 "GuardFieldLengthInstr: field state changed while compiling"); 1501 "GuardFieldLengthInstr: field state changed while compiling");
1564 } 1502 }
1565 ASSERT(!compiler->is_optimizing()); 1503 ASSERT(!compiler->is_optimizing());
1566 return; // Nothing to emit. 1504 return; // Nothing to emit.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 ASSERT(field().guarded_list_length_in_object_offset() != 1555 ASSERT(field().guarded_list_length_in_object_offset() !=
1618 Field::kUnknownLengthOffset); 1556 Field::kUnknownLengthOffset);
1619 1557
1620 __ cmpl( 1558 __ cmpl(
1621 FieldAddress(value_reg, field().guarded_list_length_in_object_offset()), 1559 FieldAddress(value_reg, field().guarded_list_length_in_object_offset()),
1622 Immediate(Smi::RawValue(field().guarded_list_length()))); 1560 Immediate(Smi::RawValue(field().guarded_list_length())));
1623 __ j(NOT_EQUAL, deopt); 1561 __ j(NOT_EQUAL, deopt);
1624 } 1562 }
1625 } 1563 }
1626 1564
1627
1628 class BoxAllocationSlowPath : public SlowPathCode { 1565 class BoxAllocationSlowPath : public SlowPathCode {
1629 public: 1566 public:
1630 BoxAllocationSlowPath(Instruction* instruction, 1567 BoxAllocationSlowPath(Instruction* instruction,
1631 const Class& cls, 1568 const Class& cls,
1632 Register result) 1569 Register result)
1633 : instruction_(instruction), cls_(cls), result_(result) {} 1570 : instruction_(instruction), cls_(cls), result_(result) {}
1634 1571
1635 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1572 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1636 if (Assembler::EmittingComments()) { 1573 if (Assembler::EmittingComments()) {
1637 __ Comment("%s slow path allocation of %s", instruction_->DebugName(), 1574 __ Comment("%s slow path allocation of %s", instruction_->DebugName(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 __ Bind(slow_path->exit_label()); 1610 __ Bind(slow_path->exit_label());
1674 } 1611 }
1675 } 1612 }
1676 1613
1677 private: 1614 private:
1678 Instruction* instruction_; 1615 Instruction* instruction_;
1679 const Class& cls_; 1616 const Class& cls_;
1680 const Register result_; 1617 const Register result_;
1681 }; 1618 };
1682 1619
1683
1684 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone, 1620 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone,
1685 bool opt) const { 1621 bool opt) const {
1686 const intptr_t kNumInputs = 2; 1622 const intptr_t kNumInputs = 2;
1687 const intptr_t kNumTemps = 1623 const intptr_t kNumTemps =
1688 (IsUnboxedStore() && opt) ? 2 : ((IsPotentialUnboxedStore()) ? 3 : 0); 1624 (IsUnboxedStore() && opt) ? 2 : ((IsPotentialUnboxedStore()) ? 3 : 0);
1689 LocationSummary* summary = new (zone) 1625 LocationSummary* summary = new (zone)
1690 LocationSummary(zone, kNumInputs, kNumTemps, 1626 LocationSummary(zone, kNumInputs, kNumTemps,
1691 ((IsUnboxedStore() && opt && is_initialization()) || 1627 ((IsUnboxedStore() && opt && is_initialization()) ||
1692 IsPotentialUnboxedStore()) 1628 IsPotentialUnboxedStore())
1693 ? LocationSummary::kCallOnSlowPath 1629 ? LocationSummary::kCallOnSlowPath
(...skipping 12 matching lines...) Expand all
1706 summary->set_temp(2, opt ? Location::RequiresFpuRegister() 1642 summary->set_temp(2, opt ? Location::RequiresFpuRegister()
1707 : Location::FpuRegisterLocation(XMM1)); 1643 : Location::FpuRegisterLocation(XMM1));
1708 } else { 1644 } else {
1709 summary->set_in(1, ShouldEmitStoreBarrier() 1645 summary->set_in(1, ShouldEmitStoreBarrier()
1710 ? Location::WritableRegister() 1646 ? Location::WritableRegister()
1711 : Location::RegisterOrConstant(value())); 1647 : Location::RegisterOrConstant(value()));
1712 } 1648 }
1713 return summary; 1649 return summary;
1714 } 1650 }
1715 1651
1716
1717 static void EnsureMutableBox(FlowGraphCompiler* compiler, 1652 static void EnsureMutableBox(FlowGraphCompiler* compiler,
1718 StoreInstanceFieldInstr* instruction, 1653 StoreInstanceFieldInstr* instruction,
1719 Register box_reg, 1654 Register box_reg,
1720 const Class& cls, 1655 const Class& cls,
1721 Register instance_reg, 1656 Register instance_reg,
1722 intptr_t offset, 1657 intptr_t offset,
1723 Register temp) { 1658 Register temp) {
1724 Label done; 1659 Label done;
1725 const Immediate& raw_null = 1660 const Immediate& raw_null =
1726 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1661 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1727 __ movl(box_reg, FieldAddress(instance_reg, offset)); 1662 __ movl(box_reg, FieldAddress(instance_reg, offset));
1728 __ cmpl(box_reg, raw_null); 1663 __ cmpl(box_reg, raw_null);
1729 __ j(NOT_EQUAL, &done); 1664 __ j(NOT_EQUAL, &done);
1730 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); 1665 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
1731 __ movl(temp, box_reg); 1666 __ movl(temp, box_reg);
1732 __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset), temp); 1667 __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset), temp);
1733 1668
1734 __ Bind(&done); 1669 __ Bind(&done);
1735 } 1670 }
1736 1671
1737
1738 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1672 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1739 ASSERT(sizeof(classid_t) == kInt16Size); 1673 ASSERT(sizeof(classid_t) == kInt16Size);
1740 Label skip_store; 1674 Label skip_store;
1741 1675
1742 Register instance_reg = locs()->in(0).reg(); 1676 Register instance_reg = locs()->in(0).reg();
1743 1677
1744 if (IsUnboxedStore() && compiler->is_optimizing()) { 1678 if (IsUnboxedStore() && compiler->is_optimizing()) {
1745 XmmRegister value = locs()->in(1).fpu_reg(); 1679 XmmRegister value = locs()->in(1).fpu_reg();
1746 Register temp = locs()->temp(0).reg(); 1680 Register temp = locs()->temp(0).reg();
1747 Register temp2 = locs()->temp(1).reg(); 1681 Register temp2 = locs()->temp(1).reg();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 Immediate(kFloat32x4Cid)); 1759 Immediate(kFloat32x4Cid));
1826 __ j(EQUAL, &store_float32x4); 1760 __ j(EQUAL, &store_float32x4);
1827 1761
1828 __ cmpw(FieldAddress(temp, Field::guarded_cid_offset()), 1762 __ cmpw(FieldAddress(temp, Field::guarded_cid_offset()),
1829 Immediate(kFloat64x2Cid)); 1763 Immediate(kFloat64x2Cid));
1830 __ j(EQUAL, &store_float64x2); 1764 __ j(EQUAL, &store_float64x2);
1831 1765
1832 // Fall through. 1766 // Fall through.
1833 __ jmp(&store_pointer); 1767 __ jmp(&store_pointer);
1834 1768
1835
1836 if (!compiler->is_optimizing()) { 1769 if (!compiler->is_optimizing()) {
1837 locs()->live_registers()->Add(locs()->in(0)); 1770 locs()->live_registers()->Add(locs()->in(0));
1838 locs()->live_registers()->Add(locs()->in(1)); 1771 locs()->live_registers()->Add(locs()->in(1));
1839 } 1772 }
1840 1773
1841 { 1774 {
1842 __ Bind(&store_double); 1775 __ Bind(&store_double);
1843 EnsureMutableBox(compiler, this, temp, compiler->double_class(), 1776 EnsureMutableBox(compiler, this, temp, compiler->double_class(),
1844 instance_reg, offset_in_bytes_, temp2); 1777 instance_reg, offset_in_bytes_, temp2);
1845 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); 1778 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset()));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 } else { 1814 } else {
1882 Register value_reg = locs()->in(1).reg(); 1815 Register value_reg = locs()->in(1).reg();
1883 __ StoreIntoObjectNoBarrier(instance_reg, 1816 __ StoreIntoObjectNoBarrier(instance_reg,
1884 FieldAddress(instance_reg, offset_in_bytes_), 1817 FieldAddress(instance_reg, offset_in_bytes_),
1885 value_reg); 1818 value_reg);
1886 } 1819 }
1887 } 1820 }
1888 __ Bind(&skip_store); 1821 __ Bind(&skip_store);
1889 } 1822 }
1890 1823
1891
1892 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(Zone* zone, 1824 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(Zone* zone,
1893 bool opt) const { 1825 bool opt) const {
1894 const intptr_t kNumInputs = 1; 1826 const intptr_t kNumInputs = 1;
1895 const intptr_t kNumTemps = 0; 1827 const intptr_t kNumTemps = 0;
1896 LocationSummary* summary = new (zone) 1828 LocationSummary* summary = new (zone)
1897 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1829 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1898 summary->set_in(0, Location::RequiresRegister()); 1830 summary->set_in(0, Location::RequiresRegister());
1899 // By specifying same register as input, our simple register allocator can 1831 // By specifying same register as input, our simple register allocator can
1900 // generate better code. 1832 // generate better code.
1901 summary->set_out(0, Location::SameAsFirstInput()); 1833 summary->set_out(0, Location::SameAsFirstInput());
1902 return summary; 1834 return summary;
1903 } 1835 }
1904 1836
1905
1906 // When the parser is building an implicit static getter for optimization, 1837 // When the parser is building an implicit static getter for optimization,
1907 // it can generate a function body where deoptimization ids do not line up 1838 // it can generate a function body where deoptimization ids do not line up
1908 // with the unoptimized code. 1839 // with the unoptimized code.
1909 // 1840 //
1910 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1841 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1911 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1842 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1912 Register field = locs()->in(0).reg(); 1843 Register field = locs()->in(0).reg();
1913 Register result = locs()->out(0).reg(); 1844 Register result = locs()->out(0).reg();
1914 __ movl(result, FieldAddress(field, Field::static_value_offset())); 1845 __ movl(result, FieldAddress(field, Field::static_value_offset()));
1915 } 1846 }
1916 1847
1917
1918 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone, 1848 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
1919 bool opt) const { 1849 bool opt) const {
1920 LocationSummary* locs = 1850 LocationSummary* locs =
1921 new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall); 1851 new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
1922 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1852 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1923 : Location::RequiresRegister()); 1853 : Location::RequiresRegister());
1924 locs->set_temp(0, Location::RequiresRegister()); 1854 locs->set_temp(0, Location::RequiresRegister());
1925 return locs; 1855 return locs;
1926 } 1856 }
1927 1857
1928
1929 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1858 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1930 Register value = locs()->in(0).reg(); 1859 Register value = locs()->in(0).reg();
1931 Register temp = locs()->temp(0).reg(); 1860 Register temp = locs()->temp(0).reg();
1932 1861
1933 __ LoadObject(temp, Field::ZoneHandle(Z, field().Original())); 1862 __ LoadObject(temp, Field::ZoneHandle(Z, field().Original()));
1934 if (this->value()->NeedsStoreBuffer()) { 1863 if (this->value()->NeedsStoreBuffer()) {
1935 __ StoreIntoObject(temp, FieldAddress(temp, Field::static_value_offset()), 1864 __ StoreIntoObject(temp, FieldAddress(temp, Field::static_value_offset()),
1936 value, CanValueBeSmi()); 1865 value, CanValueBeSmi());
1937 } else { 1866 } else {
1938 __ StoreIntoObjectNoBarrier( 1867 __ StoreIntoObjectNoBarrier(
1939 temp, FieldAddress(temp, Field::static_value_offset()), value); 1868 temp, FieldAddress(temp, Field::static_value_offset()), value);
1940 } 1869 }
1941 } 1870 }
1942 1871
1943
1944 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, 1872 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
1945 bool opt) const { 1873 bool opt) const {
1946 const intptr_t kNumInputs = 3; 1874 const intptr_t kNumInputs = 3;
1947 const intptr_t kNumTemps = 0; 1875 const intptr_t kNumTemps = 0;
1948 LocationSummary* summary = new (zone) 1876 LocationSummary* summary = new (zone)
1949 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 1877 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
1950 summary->set_in(0, Location::RegisterLocation(EAX)); // Instance. 1878 summary->set_in(0, Location::RegisterLocation(EAX)); // Instance.
1951 summary->set_in(1, Location::RegisterLocation(EDX)); // Instant. type args. 1879 summary->set_in(1, Location::RegisterLocation(EDX)); // Instant. type args.
1952 summary->set_in(2, Location::RegisterLocation(ECX)); // Function type args. 1880 summary->set_in(2, Location::RegisterLocation(ECX)); // Function type args.
1953 summary->set_out(0, Location::RegisterLocation(EAX)); 1881 summary->set_out(0, Location::RegisterLocation(EAX));
1954 return summary; 1882 return summary;
1955 } 1883 }
1956 1884
1957
1958 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1885 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1959 ASSERT(locs()->in(0).reg() == EAX); // Value. 1886 ASSERT(locs()->in(0).reg() == EAX); // Value.
1960 ASSERT(locs()->in(1).reg() == EDX); // Instantiator type arguments. 1887 ASSERT(locs()->in(1).reg() == EDX); // Instantiator type arguments.
1961 ASSERT(locs()->in(2).reg() == ECX); // Function type arguments. 1888 ASSERT(locs()->in(2).reg() == ECX); // Function type arguments.
1962 1889
1963 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); 1890 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs());
1964 ASSERT(locs()->out(0).reg() == EAX); 1891 ASSERT(locs()->out(0).reg() == EAX);
1965 } 1892 }
1966 1893
1967
1968 // TODO(srdjan): In case of constant inputs make CreateArray kNoCall and 1894 // TODO(srdjan): In case of constant inputs make CreateArray kNoCall and
1969 // use slow path stub. 1895 // use slow path stub.
1970 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, 1896 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone,
1971 bool opt) const { 1897 bool opt) const {
1972 const intptr_t kNumInputs = 2; 1898 const intptr_t kNumInputs = 2;
1973 const intptr_t kNumTemps = 0; 1899 const intptr_t kNumTemps = 0;
1974 LocationSummary* locs = new (zone) 1900 LocationSummary* locs = new (zone)
1975 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 1901 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
1976 locs->set_in(0, Location::RegisterLocation(ECX)); 1902 locs->set_in(0, Location::RegisterLocation(ECX));
1977 locs->set_in(1, Location::RegisterLocation(EDX)); 1903 locs->set_in(1, Location::RegisterLocation(EDX));
1978 locs->set_out(0, Location::RegisterLocation(EAX)); 1904 locs->set_out(0, Location::RegisterLocation(EAX));
1979 return locs; 1905 return locs;
1980 } 1906 }
1981 1907
1982
1983 // Inlines array allocation for known constant values. 1908 // Inlines array allocation for known constant values.
1984 static void InlineArrayAllocation(FlowGraphCompiler* compiler, 1909 static void InlineArrayAllocation(FlowGraphCompiler* compiler,
1985 intptr_t num_elements, 1910 intptr_t num_elements,
1986 Label* slow_path, 1911 Label* slow_path,
1987 Label* done) { 1912 Label* done) {
1988 const int kInlineArraySize = 12; // Same as kInlineInstanceSize. 1913 const int kInlineArraySize = 12; // Same as kInlineInstanceSize.
1989 const Register kLengthReg = EDX; 1914 const Register kLengthReg = EDX;
1990 const Register kElemTypeReg = ECX; 1915 const Register kElemTypeReg = ECX;
1991 const intptr_t instance_size = Array::InstanceSize(num_elements); 1916 const intptr_t instance_size = Array::InstanceSize(num_elements);
1992 1917
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 __ Bind(&init_loop); 1952 __ Bind(&init_loop);
2028 __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), Object::null_object()); 1953 __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), Object::null_object());
2029 __ addl(EDI, Immediate(kWordSize)); 1954 __ addl(EDI, Immediate(kWordSize));
2030 __ cmpl(EDI, EBX); 1955 __ cmpl(EDI, EBX);
2031 __ j(BELOW, &init_loop, Assembler::kNearJump); 1956 __ j(BELOW, &init_loop, Assembler::kNearJump);
2032 } 1957 }
2033 } 1958 }
2034 __ jmp(done, Assembler::kNearJump); 1959 __ jmp(done, Assembler::kNearJump);
2035 } 1960 }
2036 1961
2037
2038 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1962 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2039 // Allocate the array. EDX = length, ECX = element type. 1963 // Allocate the array. EDX = length, ECX = element type.
2040 const Register kLengthReg = EDX; 1964 const Register kLengthReg = EDX;
2041 const Register kElemTypeReg = ECX; 1965 const Register kElemTypeReg = ECX;
2042 const Register kResultReg = EAX; 1966 const Register kResultReg = EAX;
2043 ASSERT(locs()->in(0).reg() == kElemTypeReg); 1967 ASSERT(locs()->in(0).reg() == kElemTypeReg);
2044 ASSERT(locs()->in(1).reg() == kLengthReg); 1968 ASSERT(locs()->in(1).reg() == kLengthReg);
2045 1969
2046 Label slow_path, done; 1970 Label slow_path, done;
2047 if (compiler->is_optimizing() && num_elements()->BindsToConstant() && 1971 if (compiler->is_optimizing() && num_elements()->BindsToConstant() &&
(...skipping 19 matching lines...) Expand all
2067 const Code& stub = Code::ZoneHandle(compiler->zone(), 1991 const Code& stub = Code::ZoneHandle(compiler->zone(),
2068 StubCode::AllocateArray_entry()->code()); 1992 StubCode::AllocateArray_entry()->code());
2069 compiler->AddStubCallTarget(stub); 1993 compiler->AddStubCallTarget(stub);
2070 compiler->GenerateCallWithDeopt(token_pos(), deopt_id(), 1994 compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
2071 *StubCode::AllocateArray_entry(), 1995 *StubCode::AllocateArray_entry(),
2072 RawPcDescriptors::kOther, locs()); 1996 RawPcDescriptors::kOther, locs());
2073 __ Bind(&done); 1997 __ Bind(&done);
2074 ASSERT(locs()->out(0).reg() == kResultReg); 1998 ASSERT(locs()->out(0).reg() == kResultReg);
2075 } 1999 }
2076 2000
2077
2078 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone, 2001 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone,
2079 bool opt) const { 2002 bool opt) const {
2080 const intptr_t kNumInputs = 1; 2003 const intptr_t kNumInputs = 1;
2081 const intptr_t kNumTemps = 2004 const intptr_t kNumTemps =
2082 (IsUnboxedLoad() && opt) ? 1 : ((IsPotentialUnboxedLoad()) ? 2 : 0); 2005 (IsUnboxedLoad() && opt) ? 1 : ((IsPotentialUnboxedLoad()) ? 2 : 0);
2083 2006
2084 LocationSummary* locs = new (zone) LocationSummary( 2007 LocationSummary* locs = new (zone) LocationSummary(
2085 zone, kNumInputs, kNumTemps, (opt && !IsPotentialUnboxedLoad()) 2008 zone, kNumInputs, kNumTemps,
2086 ? LocationSummary::kNoCall 2009 (opt && !IsPotentialUnboxedLoad()) ? LocationSummary::kNoCall
2087 : LocationSummary::kCallOnSlowPath); 2010 : LocationSummary::kCallOnSlowPath);
2088 2011
2089 locs->set_in(0, Location::RequiresRegister()); 2012 locs->set_in(0, Location::RequiresRegister());
2090 2013
2091 if (IsUnboxedLoad() && opt) { 2014 if (IsUnboxedLoad() && opt) {
2092 locs->set_temp(0, Location::RequiresRegister()); 2015 locs->set_temp(0, Location::RequiresRegister());
2093 } else if (IsPotentialUnboxedLoad()) { 2016 } else if (IsPotentialUnboxedLoad()) {
2094 locs->set_temp(0, opt ? Location::RequiresFpuRegister() 2017 locs->set_temp(0, opt ? Location::RequiresFpuRegister()
2095 : Location::FpuRegisterLocation(XMM1)); 2018 : Location::FpuRegisterLocation(XMM1));
2096 locs->set_temp(1, Location::RequiresRegister()); 2019 locs->set_temp(1, Location::RequiresRegister());
2097 } 2020 }
2098 locs->set_out(0, Location::RequiresRegister()); 2021 locs->set_out(0, Location::RequiresRegister());
2099 return locs; 2022 return locs;
2100 } 2023 }
2101 2024
2102
2103 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2025 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2104 ASSERT(sizeof(classid_t) == kInt16Size); 2026 ASSERT(sizeof(classid_t) == kInt16Size);
2105 2027
2106 Register instance_reg = locs()->in(0).reg(); 2028 Register instance_reg = locs()->in(0).reg();
2107 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2029 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2108 XmmRegister result = locs()->out(0).fpu_reg(); 2030 XmmRegister result = locs()->out(0).fpu_reg();
2109 Register temp = locs()->temp(0).reg(); 2031 Register temp = locs()->temp(0).reg();
2110 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); 2032 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
2111 const intptr_t cid = field()->UnboxedFieldCid(); 2033 const intptr_t cid = field()->UnboxedFieldCid();
2112 switch (cid) { 2034 switch (cid) {
(...skipping 14 matching lines...) Expand all
2127 } 2049 }
2128 return; 2050 return;
2129 } 2051 }
2130 2052
2131 Label done; 2053 Label done;
2132 Register result = locs()->out(0).reg(); 2054 Register result = locs()->out(0).reg();
2133 if (IsPotentialUnboxedLoad()) { 2055 if (IsPotentialUnboxedLoad()) {
2134 Register temp = locs()->temp(1).reg(); 2056 Register temp = locs()->temp(1).reg();
2135 XmmRegister value = locs()->temp(0).fpu_reg(); 2057 XmmRegister value = locs()->temp(0).fpu_reg();
2136 2058
2137
2138 Label load_pointer; 2059 Label load_pointer;
2139 Label load_double; 2060 Label load_double;
2140 Label load_float32x4; 2061 Label load_float32x4;
2141 Label load_float64x2; 2062 Label load_float64x2;
2142 2063
2143 __ LoadObject(result, Field::ZoneHandle(field()->Original())); 2064 __ LoadObject(result, Field::ZoneHandle(field()->Original()));
2144 2065
2145 FieldAddress field_cid_operand(result, Field::guarded_cid_offset()); 2066 FieldAddress field_cid_operand(result, Field::guarded_cid_offset());
2146 FieldAddress field_nullability_operand(result, Field::is_nullable_offset()); 2067 FieldAddress field_nullability_operand(result, Field::is_nullable_offset());
2147 2068
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2193 __ movups(FieldAddress(result, Float64x2::value_offset()), value); 2114 __ movups(FieldAddress(result, Float64x2::value_offset()), value);
2194 __ jmp(&done); 2115 __ jmp(&done);
2195 } 2116 }
2196 2117
2197 __ Bind(&load_pointer); 2118 __ Bind(&load_pointer);
2198 } 2119 }
2199 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); 2120 __ movl(result, FieldAddress(instance_reg, offset_in_bytes()));
2200 __ Bind(&done); 2121 __ Bind(&done);
2201 } 2122 }
2202 2123
2203
2204 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, 2124 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
2205 bool opt) const { 2125 bool opt) const {
2206 const intptr_t kNumInputs = 2; 2126 const intptr_t kNumInputs = 2;
2207 const intptr_t kNumTemps = 0; 2127 const intptr_t kNumTemps = 0;
2208 LocationSummary* locs = new (zone) 2128 LocationSummary* locs = new (zone)
2209 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2129 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2210 locs->set_in(0, Location::RegisterLocation(EAX)); // Instant. type args. 2130 locs->set_in(0, Location::RegisterLocation(EAX)); // Instant. type args.
2211 locs->set_in(1, Location::RegisterLocation(EDX)); // Function type args. 2131 locs->set_in(1, Location::RegisterLocation(EDX)); // Function type args.
2212 locs->set_out(0, Location::RegisterLocation(EAX)); 2132 locs->set_out(0, Location::RegisterLocation(EAX));
2213 return locs; 2133 return locs;
2214 } 2134 }
2215 2135
2216
2217 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2136 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2218 Register instantiator_type_args_reg = locs()->in(0).reg(); 2137 Register instantiator_type_args_reg = locs()->in(0).reg();
2219 Register function_type_args_reg = locs()->in(1).reg(); 2138 Register function_type_args_reg = locs()->in(1).reg();
2220 Register result_reg = locs()->out(0).reg(); 2139 Register result_reg = locs()->out(0).reg();
2221 2140
2222 // 'instantiator_type_args_reg' is a TypeArguments object (or null). 2141 // 'instantiator_type_args_reg' is a TypeArguments object (or null).
2223 // 'function_type_args_reg' is a TypeArguments object (or null). 2142 // 'function_type_args_reg' is a TypeArguments object (or null).
2224 // A runtime call to instantiate the type is required. 2143 // A runtime call to instantiate the type is required.
2225 __ PushObject(Object::null_object()); // Make room for the result. 2144 __ PushObject(Object::null_object()); // Make room for the result.
2226 __ PushObject(type()); 2145 __ PushObject(type());
2227 __ pushl(instantiator_type_args_reg); // Push instantiator type arguments. 2146 __ pushl(instantiator_type_args_reg); // Push instantiator type arguments.
2228 __ pushl(function_type_args_reg); // Push function type arguments. 2147 __ pushl(function_type_args_reg); // Push function type arguments.
2229 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), 2148 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2230 kInstantiateTypeRuntimeEntry, 3, locs()); 2149 kInstantiateTypeRuntimeEntry, 3, locs());
2231 __ Drop(3); // Drop 2 type argument vectors and uninstantiated type. 2150 __ Drop(3); // Drop 2 type argument vectors and uninstantiated type.
2232 __ popl(result_reg); // Pop instantiated type. 2151 __ popl(result_reg); // Pop instantiated type.
2233 ASSERT(instantiator_type_args_reg == result_reg); 2152 ASSERT(instantiator_type_args_reg == result_reg);
2234 } 2153 }
2235 2154
2236
2237 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( 2155 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2238 Zone* zone, 2156 Zone* zone,
2239 bool opt) const { 2157 bool opt) const {
2240 const intptr_t kNumInputs = 2; 2158 const intptr_t kNumInputs = 2;
2241 const intptr_t kNumTemps = 0; 2159 const intptr_t kNumTemps = 0;
2242 LocationSummary* locs = new (zone) 2160 LocationSummary* locs = new (zone)
2243 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2161 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2244 locs->set_in(0, Location::RegisterLocation(EAX)); // Instant. type args. 2162 locs->set_in(0, Location::RegisterLocation(EAX)); // Instant. type args.
2245 locs->set_in(1, Location::RegisterLocation(ECX)); // Function type args. 2163 locs->set_in(1, Location::RegisterLocation(ECX)); // Function type args.
2246 locs->set_out(0, Location::RegisterLocation(EAX)); 2164 locs->set_out(0, Location::RegisterLocation(EAX));
2247 return locs; 2165 return locs;
2248 } 2166 }
2249 2167
2250
2251 void InstantiateTypeArgumentsInstr::EmitNativeCode( 2168 void InstantiateTypeArgumentsInstr::EmitNativeCode(
2252 FlowGraphCompiler* compiler) { 2169 FlowGraphCompiler* compiler) {
2253 Register instantiator_type_args_reg = locs()->in(0).reg(); 2170 Register instantiator_type_args_reg = locs()->in(0).reg();
2254 Register function_type_args_reg = locs()->in(1).reg(); 2171 Register function_type_args_reg = locs()->in(1).reg();
2255 Register result_reg = locs()->out(0).reg(); 2172 Register result_reg = locs()->out(0).reg();
2256 ASSERT(instantiator_type_args_reg == EAX); 2173 ASSERT(instantiator_type_args_reg == EAX);
2257 ASSERT(instantiator_type_args_reg == result_reg); 2174 ASSERT(instantiator_type_args_reg == result_reg);
2258 2175
2259 // 'instantiator_type_args_reg' is a TypeArguments object (or null). 2176 // 'instantiator_type_args_reg' is a TypeArguments object (or null).
2260 // 'function_type_args_reg' is a TypeArguments object (or null). 2177 // 'function_type_args_reg' is a TypeArguments object (or null).
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2309 __ pushl(instantiator_type_args_reg); // Push instantiator type arguments. 2226 __ pushl(instantiator_type_args_reg); // Push instantiator type arguments.
2310 __ pushl(function_type_args_reg); // Push function type arguments. 2227 __ pushl(function_type_args_reg); // Push function type arguments.
2311 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), 2228 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2312 kInstantiateTypeArgumentsRuntimeEntry, 3, 2229 kInstantiateTypeArgumentsRuntimeEntry, 3,
2313 locs()); 2230 locs());
2314 __ Drop(3); // Drop 2 type argument vectors and uninstantiated args. 2231 __ Drop(3); // Drop 2 type argument vectors and uninstantiated args.
2315 __ popl(result_reg); // Pop instantiated type arguments. 2232 __ popl(result_reg); // Pop instantiated type arguments.
2316 __ Bind(&type_arguments_instantiated); 2233 __ Bind(&type_arguments_instantiated);
2317 } 2234 }
2318 2235
2319
2320 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( 2236 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
2321 Zone* zone, 2237 Zone* zone,
2322 bool opt) const { 2238 bool opt) const {
2323 ASSERT(opt); 2239 ASSERT(opt);
2324 const intptr_t kNumInputs = 0; 2240 const intptr_t kNumInputs = 0;
2325 const intptr_t kNumTemps = 2; 2241 const intptr_t kNumTemps = 2;
2326 LocationSummary* locs = new (zone) LocationSummary( 2242 LocationSummary* locs = new (zone) LocationSummary(
2327 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 2243 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2328 locs->set_temp(0, Location::RegisterLocation(ECX)); 2244 locs->set_temp(0, Location::RegisterLocation(ECX));
2329 locs->set_temp(1, Location::RegisterLocation(EDI)); 2245 locs->set_temp(1, Location::RegisterLocation(EDI));
2330 locs->set_out(0, Location::RegisterLocation(EAX)); 2246 locs->set_out(0, Location::RegisterLocation(EAX));
2331 return locs; 2247 return locs;
2332 } 2248 }
2333 2249
2334
2335 class AllocateContextSlowPath : public SlowPathCode { 2250 class AllocateContextSlowPath : public SlowPathCode {
2336 public: 2251 public:
2337 explicit AllocateContextSlowPath( 2252 explicit AllocateContextSlowPath(
2338 AllocateUninitializedContextInstr* instruction) 2253 AllocateUninitializedContextInstr* instruction)
2339 : instruction_(instruction) {} 2254 : instruction_(instruction) {}
2340 2255
2341 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2256 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2342 __ Comment("AllocateContextSlowPath"); 2257 __ Comment("AllocateContextSlowPath");
2343 __ Bind(entry_label()); 2258 __ Bind(entry_label());
2344 2259
(...skipping 11 matching lines...) Expand all
2356 RawPcDescriptors::kOther, locs); 2271 RawPcDescriptors::kOther, locs);
2357 ASSERT(instruction_->locs()->out(0).reg() == EAX); 2272 ASSERT(instruction_->locs()->out(0).reg() == EAX);
2358 compiler->RestoreLiveRegisters(instruction_->locs()); 2273 compiler->RestoreLiveRegisters(instruction_->locs());
2359 __ jmp(exit_label()); 2274 __ jmp(exit_label());
2360 } 2275 }
2361 2276
2362 private: 2277 private:
2363 AllocateUninitializedContextInstr* instruction_; 2278 AllocateUninitializedContextInstr* instruction_;
2364 }; 2279 };
2365 2280
2366
2367 void AllocateUninitializedContextInstr::EmitNativeCode( 2281 void AllocateUninitializedContextInstr::EmitNativeCode(
2368 FlowGraphCompiler* compiler) { 2282 FlowGraphCompiler* compiler) {
2369 ASSERT(compiler->is_optimizing()); 2283 ASSERT(compiler->is_optimizing());
2370 Register temp = locs()->temp(0).reg(); 2284 Register temp = locs()->temp(0).reg();
2371 Register temp2 = locs()->temp(1).reg(); 2285 Register temp2 = locs()->temp(1).reg();
2372 Register result = locs()->out(0).reg(); 2286 Register result = locs()->out(0).reg();
2373 // Try allocate the object. 2287 // Try allocate the object.
2374 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this); 2288 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
2375 compiler->AddSlowPathCode(slow_path); 2289 compiler->AddSlowPathCode(slow_path);
2376 intptr_t instance_size = Context::InstanceSize(num_context_variables()); 2290 intptr_t instance_size = Context::InstanceSize(num_context_variables());
2377 2291
2378 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(), 2292 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
2379 Assembler::kFarJump, 2293 Assembler::kFarJump,
2380 result, // instance 2294 result, // instance
2381 temp, // end address 2295 temp, // end address
2382 temp2); // temp 2296 temp2); // temp
2383 2297
2384 // Setup up number of context variables field. 2298 // Setup up number of context variables field.
2385 __ movl(FieldAddress(result, Context::num_variables_offset()), 2299 __ movl(FieldAddress(result, Context::num_variables_offset()),
2386 Immediate(num_context_variables())); 2300 Immediate(num_context_variables()));
2387 2301
2388 __ Bind(slow_path->exit_label()); 2302 __ Bind(slow_path->exit_label());
2389 } 2303 }
2390 2304
2391
2392 LocationSummary* AllocateContextInstr::MakeLocationSummary(Zone* zone, 2305 LocationSummary* AllocateContextInstr::MakeLocationSummary(Zone* zone,
2393 bool opt) const { 2306 bool opt) const {
2394 const intptr_t kNumInputs = 0; 2307 const intptr_t kNumInputs = 0;
2395 const intptr_t kNumTemps = 1; 2308 const intptr_t kNumTemps = 1;
2396 LocationSummary* locs = new (zone) 2309 LocationSummary* locs = new (zone)
2397 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2310 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2398 locs->set_temp(0, Location::RegisterLocation(EDX)); 2311 locs->set_temp(0, Location::RegisterLocation(EDX));
2399 locs->set_out(0, Location::RegisterLocation(EAX)); 2312 locs->set_out(0, Location::RegisterLocation(EAX));
2400 return locs; 2313 return locs;
2401 } 2314 }
2402 2315
2403
2404 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2316 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2405 ASSERT(locs()->temp(0).reg() == EDX); 2317 ASSERT(locs()->temp(0).reg() == EDX);
2406 ASSERT(locs()->out(0).reg() == EAX); 2318 ASSERT(locs()->out(0).reg() == EAX);
2407 2319
2408 __ movl(EDX, Immediate(num_context_variables())); 2320 __ movl(EDX, Immediate(num_context_variables()));
2409 compiler->GenerateCall(token_pos(), *StubCode::AllocateContext_entry(), 2321 compiler->GenerateCall(token_pos(), *StubCode::AllocateContext_entry(),
2410 RawPcDescriptors::kOther, locs()); 2322 RawPcDescriptors::kOther, locs());
2411 } 2323 }
2412 2324
2413
2414 LocationSummary* InitStaticFieldInstr::MakeLocationSummary(Zone* zone, 2325 LocationSummary* InitStaticFieldInstr::MakeLocationSummary(Zone* zone,
2415 bool opt) const { 2326 bool opt) const {
2416 const intptr_t kNumInputs = 1; 2327 const intptr_t kNumInputs = 1;
2417 const intptr_t kNumTemps = 1; 2328 const intptr_t kNumTemps = 1;
2418 LocationSummary* locs = new (zone) 2329 LocationSummary* locs = new (zone)
2419 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2330 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2420 locs->set_in(0, Location::RegisterLocation(EAX)); 2331 locs->set_in(0, Location::RegisterLocation(EAX));
2421 locs->set_temp(0, Location::RegisterLocation(ECX)); 2332 locs->set_temp(0, Location::RegisterLocation(ECX));
2422 return locs; 2333 return locs;
2423 } 2334 }
2424 2335
2425
2426 void InitStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2336 void InitStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2427 Register field = locs()->in(0).reg(); 2337 Register field = locs()->in(0).reg();
2428 Register temp = locs()->temp(0).reg(); 2338 Register temp = locs()->temp(0).reg();
2429 2339
2430 Label call_runtime, no_call; 2340 Label call_runtime, no_call;
2431 2341
2432 __ movl(temp, FieldAddress(field, Field::static_value_offset())); 2342 __ movl(temp, FieldAddress(field, Field::static_value_offset()));
2433 __ CompareObject(temp, Object::sentinel()); 2343 __ CompareObject(temp, Object::sentinel());
2434 __ j(EQUAL, &call_runtime); 2344 __ j(EQUAL, &call_runtime);
2435 2345
2436 __ CompareObject(temp, Object::transition_sentinel()); 2346 __ CompareObject(temp, Object::transition_sentinel());
2437 __ j(NOT_EQUAL, &no_call); 2347 __ j(NOT_EQUAL, &no_call);
2438 2348
2439 __ Bind(&call_runtime); 2349 __ Bind(&call_runtime);
2440 __ PushObject(Object::null_object()); // Make room for (unused) result. 2350 __ PushObject(Object::null_object()); // Make room for (unused) result.
2441 __ pushl(field); 2351 __ pushl(field);
2442 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), 2352 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2443 kInitStaticFieldRuntimeEntry, 1, locs()); 2353 kInitStaticFieldRuntimeEntry, 1, locs());
2444 __ Drop(2); // Remove argument and unused result. 2354 __ Drop(2); // Remove argument and unused result.
2445 __ Bind(&no_call); 2355 __ Bind(&no_call);
2446 } 2356 }
2447 2357
2448
2449 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone, 2358 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
2450 bool opt) const { 2359 bool opt) const {
2451 const intptr_t kNumInputs = 1; 2360 const intptr_t kNumInputs = 1;
2452 const intptr_t kNumTemps = 0; 2361 const intptr_t kNumTemps = 0;
2453 LocationSummary* locs = new (zone) 2362 LocationSummary* locs = new (zone)
2454 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 2363 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
2455 locs->set_in(0, Location::RegisterLocation(EAX)); 2364 locs->set_in(0, Location::RegisterLocation(EAX));
2456 locs->set_out(0, Location::RegisterLocation(EAX)); 2365 locs->set_out(0, Location::RegisterLocation(EAX));
2457 return locs; 2366 return locs;
2458 } 2367 }
2459 2368
2460
2461 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2369 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2462 Register context_value = locs()->in(0).reg(); 2370 Register context_value = locs()->in(0).reg();
2463 Register result = locs()->out(0).reg(); 2371 Register result = locs()->out(0).reg();
2464 2372
2465 __ PushObject(Object::null_object()); // Make room for the result. 2373 __ PushObject(Object::null_object()); // Make room for the result.
2466 __ pushl(context_value); 2374 __ pushl(context_value);
2467 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), 2375 compiler->GenerateRuntimeCall(token_pos(), deopt_id(),
2468 kCloneContextRuntimeEntry, 1, locs()); 2376 kCloneContextRuntimeEntry, 1, locs());
2469 __ popl(result); // Remove argument. 2377 __ popl(result); // Remove argument.
2470 __ popl(result); // Get result (cloned context). 2378 __ popl(result); // Get result (cloned context).
2471 } 2379 }
2472 2380
2473
2474 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone, 2381 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
2475 bool opt) const { 2382 bool opt) const {
2476 UNREACHABLE(); 2383 UNREACHABLE();
2477 return NULL; 2384 return NULL;
2478 } 2385 }
2479 2386
2480
2481 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2387 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2482 __ Bind(compiler->GetJumpLabel(this)); 2388 __ Bind(compiler->GetJumpLabel(this));
2483 compiler->AddExceptionHandler(catch_try_index(), try_index(), 2389 compiler->AddExceptionHandler(catch_try_index(), try_index(),
2484 compiler->assembler()->CodeSize(), 2390 compiler->assembler()->CodeSize(),
2485 handler_token_pos(), is_generated(), 2391 handler_token_pos(), is_generated(),
2486 catch_handler_types_, needs_stacktrace()); 2392 catch_handler_types_, needs_stacktrace());
2487 // On lazy deoptimization we patch the optimized code here to enter the 2393 // On lazy deoptimization we patch the optimized code here to enter the
2488 // deoptimization stub. 2394 // deoptimization stub.
2489 const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); 2395 const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
2490 if (compiler->is_optimizing()) { 2396 if (compiler->is_optimizing()) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 } else { 2451 } else {
2546 // Restore stack and initialize the two exception variables: 2452 // Restore stack and initialize the two exception variables:
2547 // exception and stack trace variables. 2453 // exception and stack trace variables.
2548 __ movl(Address(EBP, exception_var().index() * kWordSize), 2454 __ movl(Address(EBP, exception_var().index() * kWordSize),
2549 kExceptionObjectReg); 2455 kExceptionObjectReg);
2550 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), 2456 __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
2551 kStackTraceObjectReg); 2457 kStackTraceObjectReg);
2552 } 2458 }
2553 } 2459 }
2554 2460
2555
2556 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(Zone* zone, 2461 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(Zone* zone,
2557 bool opt) const { 2462 bool opt) const {
2558 const intptr_t kNumInputs = 0; 2463 const intptr_t kNumInputs = 0;
2559 const intptr_t kNumTemps = opt ? 0 : 1; 2464 const intptr_t kNumTemps = opt ? 0 : 1;
2560 LocationSummary* summary = new (zone) LocationSummary( 2465 LocationSummary* summary = new (zone) LocationSummary(
2561 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 2466 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2562 if (!opt) { 2467 if (!opt) {
2563 summary->set_temp(0, Location::RequiresRegister()); 2468 summary->set_temp(0, Location::RequiresRegister());
2564 } 2469 }
2565 return summary; 2470 return summary;
2566 } 2471 }
2567 2472
2568
2569 class CheckStackOverflowSlowPath : public SlowPathCode { 2473 class CheckStackOverflowSlowPath : public SlowPathCode {
2570 public: 2474 public:
2571 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) 2475 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction)
2572 : instruction_(instruction) {} 2476 : instruction_(instruction) {}
2573 2477
2574 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2478 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2575 if (compiler->isolate()->use_osr() && osr_entry_label()->IsLinked()) { 2479 if (compiler->isolate()->use_osr() && osr_entry_label()->IsLinked()) {
2576 __ Comment("CheckStackOverflowSlowPathOsr"); 2480 __ Comment("CheckStackOverflowSlowPathOsr");
2577 __ Bind(osr_entry_label()); 2481 __ Bind(osr_entry_label());
2578 __ movl(Address(THR, Thread::stack_overflow_flags_offset()), 2482 __ movl(Address(THR, Thread::stack_overflow_flags_offset()),
(...skipping 26 matching lines...) Expand all
2605 Label* osr_entry_label() { 2509 Label* osr_entry_label() {
2606 ASSERT(Isolate::Current()->use_osr()); 2510 ASSERT(Isolate::Current()->use_osr());
2607 return &osr_entry_label_; 2511 return &osr_entry_label_;
2608 } 2512 }
2609 2513
2610 private: 2514 private:
2611 CheckStackOverflowInstr* instruction_; 2515 CheckStackOverflowInstr* instruction_;
2612 Label osr_entry_label_; 2516 Label osr_entry_label_;
2613 }; 2517 };
2614 2518
2615
2616 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2519 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2617 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); 2520 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
2618 compiler->AddSlowPathCode(slow_path); 2521 compiler->AddSlowPathCode(slow_path);
2619 2522
2620 __ cmpl(ESP, Address(THR, Thread::stack_limit_offset())); 2523 __ cmpl(ESP, Address(THR, Thread::stack_limit_offset()));
2621 __ j(BELOW_EQUAL, slow_path->entry_label()); 2524 __ j(BELOW_EQUAL, slow_path->entry_label());
2622 if (compiler->CanOSRFunction() && in_loop()) { 2525 if (compiler->CanOSRFunction() && in_loop()) {
2623 // In unoptimized code check the usage counter to trigger OSR at loop 2526 // In unoptimized code check the usage counter to trigger OSR at loop
2624 // stack checks. Use progressively higher thresholds for more deeply 2527 // stack checks. Use progressively higher thresholds for more deeply
2625 // nested loops to attempt to hit outer loops with OSR when possible. 2528 // nested loops to attempt to hit outer loops with OSR when possible.
2626 __ LoadObject(EDI, compiler->parsed_function().function()); 2529 __ LoadObject(EDI, compiler->parsed_function().function());
2627 intptr_t threshold = 2530 intptr_t threshold =
2628 FLAG_optimization_counter_threshold * (loop_depth() + 1); 2531 FLAG_optimization_counter_threshold * (loop_depth() + 1);
2629 __ cmpl(FieldAddress(EDI, Function::usage_counter_offset()), 2532 __ cmpl(FieldAddress(EDI, Function::usage_counter_offset()),
2630 Immediate(threshold)); 2533 Immediate(threshold));
2631 __ j(GREATER_EQUAL, slow_path->osr_entry_label()); 2534 __ j(GREATER_EQUAL, slow_path->osr_entry_label());
2632 } 2535 }
2633 if (compiler->ForceSlowPathForStackOverflow()) { 2536 if (compiler->ForceSlowPathForStackOverflow()) {
2634 // TODO(turnidge): Implement stack overflow count in assembly to 2537 // TODO(turnidge): Implement stack overflow count in assembly to
2635 // make --stacktrace-every and --deoptimize-every faster. 2538 // make --stacktrace-every and --deoptimize-every faster.
2636 __ jmp(slow_path->entry_label()); 2539 __ jmp(slow_path->entry_label());
2637 } 2540 }
2638 __ Bind(slow_path->exit_label()); 2541 __ Bind(slow_path->exit_label());
2639 } 2542 }
2640 2543
2641
2642 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2544 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2643 BinarySmiOpInstr* shift_left) { 2545 BinarySmiOpInstr* shift_left) {
2644 const LocationSummary& locs = *shift_left->locs(); 2546 const LocationSummary& locs = *shift_left->locs();
2645 Register left = locs.in(0).reg(); 2547 Register left = locs.in(0).reg();
2646 Register result = locs.out(0).reg(); 2548 Register result = locs.out(0).reg();
2647 ASSERT(left == result); 2549 ASSERT(left == result);
2648 Label* deopt = shift_left->CanDeoptimize() 2550 Label* deopt = shift_left->CanDeoptimize()
2649 ? compiler->AddDeoptStub(shift_left->deopt_id(), 2551 ? compiler->AddDeoptStub(shift_left->deopt_id(),
2650 ICData::kDeoptBinarySmiOp) 2552 ICData::kDeoptBinarySmiOp)
2651 : NULL; 2553 : NULL;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2743 // Overflow test (preserve temp and right); 2645 // Overflow test (preserve temp and right);
2744 __ shll(left, right); 2646 __ shll(left, right);
2745 __ sarl(left, right); 2647 __ sarl(left, right);
2746 __ cmpl(left, temp); 2648 __ cmpl(left, temp);
2747 __ j(NOT_EQUAL, deopt); // Overflow. 2649 __ j(NOT_EQUAL, deopt); // Overflow.
2748 // Shift for result now we know there is no overflow. 2650 // Shift for result now we know there is no overflow.
2749 __ shll(left, right); 2651 __ shll(left, right);
2750 } 2652 }
2751 } 2653 }
2752 2654
2753
2754 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, 2655 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone,
2755 bool opt) const { 2656 bool opt) const {
2756 // Only for precompiled code, not on ia32 currently. 2657 // Only for precompiled code, not on ia32 currently.
2757 UNIMPLEMENTED(); 2658 UNIMPLEMENTED();
2758 return NULL; 2659 return NULL;
2759 } 2660 }
2760 2661
2761
2762 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2662 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2763 // Only for precompiled code, not on ia32 currently. 2663 // Only for precompiled code, not on ia32 currently.
2764 UNIMPLEMENTED(); 2664 UNIMPLEMENTED();
2765 } 2665 }
2766 2666
2767
2768 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary( 2667 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
2769 Zone* zone, 2668 Zone* zone,
2770 bool opt) const { 2669 bool opt) const {
2771 // Only for precompiled code, not on ia32 currently. 2670 // Only for precompiled code, not on ia32 currently.
2772 UNIMPLEMENTED(); 2671 UNIMPLEMENTED();
2773 return NULL; 2672 return NULL;
2774 } 2673 }
2775 2674
2776
2777 Condition CheckedSmiComparisonInstr::EmitComparisonCode( 2675 Condition CheckedSmiComparisonInstr::EmitComparisonCode(
2778 FlowGraphCompiler* compiler, 2676 FlowGraphCompiler* compiler,
2779 BranchLabels labels) { 2677 BranchLabels labels) {
2780 // Only for precompiled code, not on ia32 currently. 2678 // Only for precompiled code, not on ia32 currently.
2781 UNIMPLEMENTED(); 2679 UNIMPLEMENTED();
2782 return ZERO; 2680 return ZERO;
2783 } 2681 }
2784 2682
2785
2786 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 2683 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
2787 BranchInstr* instr) { 2684 BranchInstr* instr) {
2788 // Only for precompiled code, not on ia32 currently. 2685 // Only for precompiled code, not on ia32 currently.
2789 UNIMPLEMENTED(); 2686 UNIMPLEMENTED();
2790 } 2687 }
2791 2688
2792
2793 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2689 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2794 // Only for precompiled code, not on ia32 currently. 2690 // Only for precompiled code, not on ia32 currently.
2795 UNIMPLEMENTED(); 2691 UNIMPLEMENTED();
2796 } 2692 }
2797 2693
2798
2799 static bool IsSmiValue(const Object& constant, intptr_t value) { 2694 static bool IsSmiValue(const Object& constant, intptr_t value) {
2800 return constant.IsSmi() && (Smi::Cast(constant).Value() == value); 2695 return constant.IsSmi() && (Smi::Cast(constant).Value() == value);
2801 } 2696 }
2802 2697
2803
2804 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, 2698 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
2805 bool opt) const { 2699 bool opt) const {
2806 const intptr_t kNumInputs = 2; 2700 const intptr_t kNumInputs = 2;
2807 if (op_kind() == Token::kTRUNCDIV) { 2701 if (op_kind() == Token::kTRUNCDIV) {
2808 const intptr_t kNumTemps = 1; 2702 const intptr_t kNumTemps = 1;
2809 LocationSummary* summary = new (zone) 2703 LocationSummary* summary = new (zone)
2810 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 2704 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
2811 if (RightIsPowerOfTwoConstant()) { 2705 if (RightIsPowerOfTwoConstant()) {
2812 summary->set_in(0, Location::RequiresRegister()); 2706 summary->set_in(0, Location::RequiresRegister());
2813 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2707 ConstantInstr* right_constant = right()->definition()->AsConstant();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2867 if (constant != NULL) { 2761 if (constant != NULL) {
2868 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2762 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2869 } else { 2763 } else {
2870 summary->set_in(1, Location::PrefersRegister()); 2764 summary->set_in(1, Location::PrefersRegister());
2871 } 2765 }
2872 summary->set_out(0, Location::SameAsFirstInput()); 2766 summary->set_out(0, Location::SameAsFirstInput());
2873 return summary; 2767 return summary;
2874 } 2768 }
2875 } 2769 }
2876 2770
2877
2878 template <typename OperandType> 2771 template <typename OperandType>
2879 static void EmitIntegerArithmetic(FlowGraphCompiler* compiler, 2772 static void EmitIntegerArithmetic(FlowGraphCompiler* compiler,
2880 Token::Kind op_kind, 2773 Token::Kind op_kind,
2881 Register left, 2774 Register left,
2882 const OperandType& right, 2775 const OperandType& right,
2883 Label* deopt) { 2776 Label* deopt) {
2884 switch (op_kind) { 2777 switch (op_kind) {
2885 case Token::kADD: 2778 case Token::kADD:
2886 __ addl(left, right); 2779 __ addl(left, right);
2887 break; 2780 break;
(...skipping 11 matching lines...) Expand all
2899 break; 2792 break;
2900 case Token::kMUL: 2793 case Token::kMUL:
2901 __ imull(left, right); 2794 __ imull(left, right);
2902 break; 2795 break;
2903 default: 2796 default:
2904 UNREACHABLE(); 2797 UNREACHABLE();
2905 } 2798 }
2906 if (deopt != NULL) __ j(OVERFLOW, deopt); 2799 if (deopt != NULL) __ j(OVERFLOW, deopt);
2907 } 2800 }
2908 2801
2909
2910 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2802 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2911 if (op_kind() == Token::kSHL) { 2803 if (op_kind() == Token::kSHL) {
2912 EmitSmiShiftLeft(compiler, this); 2804 EmitSmiShiftLeft(compiler, this);
2913 return; 2805 return;
2914 } 2806 }
2915 2807
2916 Register left = locs()->in(0).reg(); 2808 Register left = locs()->in(0).reg();
2917 Register result = locs()->out(0).reg(); 2809 Register result = locs()->out(0).reg();
2918 ASSERT(left == result); 2810 ASSERT(left == result);
2919 Label* deopt = NULL; 2811 Label* deopt = NULL;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 case Token::kBIT_AND: 2883 case Token::kBIT_AND:
2992 case Token::kBIT_OR: 2884 case Token::kBIT_OR:
2993 case Token::kBIT_XOR: 2885 case Token::kBIT_XOR:
2994 case Token::kMUL: 2886 case Token::kMUL:
2995 if (op_kind() == Token::kMUL) { 2887 if (op_kind() == Token::kMUL) {
2996 __ SmiUntag(left); 2888 __ SmiUntag(left);
2997 } 2889 }
2998 EmitIntegerArithmetic(compiler, op_kind(), left, right, deopt); 2890 EmitIntegerArithmetic(compiler, op_kind(), left, right, deopt);
2999 break; 2891 break;
3000 2892
3001
3002 case Token::kTRUNCDIV: { 2893 case Token::kTRUNCDIV: {
3003 if (RangeUtils::CanBeZero(right_range())) { 2894 if (RangeUtils::CanBeZero(right_range())) {
3004 // Handle divide by zero in runtime. 2895 // Handle divide by zero in runtime.
3005 __ testl(right, right); 2896 __ testl(right, right);
3006 __ j(ZERO, deopt); 2897 __ j(ZERO, deopt);
3007 } 2898 }
3008 ASSERT(left == EAX); 2899 ASSERT(left == EAX);
3009 ASSERT((right != EDX) && (right != EAX)); 2900 ASSERT((right != EDX) && (right != EAX));
3010 ASSERT(locs()->temp(0).reg() == EDX); 2901 ASSERT(locs()->temp(0).reg() == EDX);
3011 ASSERT(result == EAX); 2902 ASSERT(result == EAX);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 // behavior (short-circuit evaluation). 2991 // behavior (short-circuit evaluation).
3101 UNREACHABLE(); 2992 UNREACHABLE();
3102 break; 2993 break;
3103 } 2994 }
3104 default: 2995 default:
3105 UNREACHABLE(); 2996 UNREACHABLE();
3106 break; 2997 break;
3107 } 2998 }
3108 } 2999 }
3109 3000
3110
3111 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Zone* zone, 3001 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Zone* zone,
3112 bool opt) const { 3002 bool opt) const {
3113 const intptr_t kNumInputs = 2; 3003 const intptr_t kNumInputs = 2;
3114 if (op_kind() == Token::kTRUNCDIV) { 3004 if (op_kind() == Token::kTRUNCDIV) {
3115 UNREACHABLE(); 3005 UNREACHABLE();
3116 return NULL; 3006 return NULL;
3117 } else if (op_kind() == Token::kMOD) { 3007 } else if (op_kind() == Token::kMOD) {
3118 UNREACHABLE(); 3008 UNREACHABLE();
3119 return NULL; 3009 return NULL;
3120 } else if (op_kind() == Token::kSHR) { 3010 } else if (op_kind() == Token::kSHR) {
(...skipping 24 matching lines...) Expand all
3145 if (constant != NULL) { 3035 if (constant != NULL) {
3146 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 3036 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
3147 } else { 3037 } else {
3148 summary->set_in(1, Location::PrefersRegister()); 3038 summary->set_in(1, Location::PrefersRegister());
3149 } 3039 }
3150 summary->set_out(0, Location::SameAsFirstInput()); 3040 summary->set_out(0, Location::SameAsFirstInput());
3151 return summary; 3041 return summary;
3152 } 3042 }
3153 } 3043 }
3154 3044
3155
3156 static void EmitInt32ShiftLeft(FlowGraphCompiler* compiler, 3045 static void EmitInt32ShiftLeft(FlowGraphCompiler* compiler,
3157 BinaryInt32OpInstr* shift_left) { 3046 BinaryInt32OpInstr* shift_left) {
3158 const LocationSummary& locs = *shift_left->locs(); 3047 const LocationSummary& locs = *shift_left->locs();
3159 Register left = locs.in(0).reg(); 3048 Register left = locs.in(0).reg();
3160 Register result = locs.out(0).reg(); 3049 Register result = locs.out(0).reg();
3161 ASSERT(left == result); 3050 ASSERT(left == result);
3162 Label* deopt = shift_left->CanDeoptimize() 3051 Label* deopt = shift_left->CanDeoptimize()
3163 ? compiler->AddDeoptStub(shift_left->deopt_id(), 3052 ? compiler->AddDeoptStub(shift_left->deopt_id(),
3164 ICData::kDeoptBinarySmiOp) 3053 ICData::kDeoptBinarySmiOp)
3165 : NULL; 3054 : NULL;
(...skipping 11 matching lines...) Expand all
3177 __ movl(temp, left); 3066 __ movl(temp, left);
3178 __ shll(left, Immediate(value)); 3067 __ shll(left, Immediate(value));
3179 __ sarl(left, Immediate(value)); 3068 __ sarl(left, Immediate(value));
3180 __ cmpl(left, temp); 3069 __ cmpl(left, temp);
3181 __ j(NOT_EQUAL, deopt); // Overflow. 3070 __ j(NOT_EQUAL, deopt); // Overflow.
3182 } 3071 }
3183 // Shift for result now we know there is no overflow. 3072 // Shift for result now we know there is no overflow.
3184 __ shll(left, Immediate(value)); 3073 __ shll(left, Immediate(value));
3185 } 3074 }
3186 3075
3187
3188 void BinaryInt32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3076 void BinaryInt32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3189 if (op_kind() == Token::kSHL) { 3077 if (op_kind() == Token::kSHL) {
3190 EmitInt32ShiftLeft(compiler, this); 3078 EmitInt32ShiftLeft(compiler, this);
3191 return; 3079 return;
3192 } 3080 }
3193 3081
3194 Register left = locs()->in(0).reg(); 3082 Register left = locs()->in(0).reg();
3195 Register result = locs()->out(0).reg(); 3083 Register result = locs()->out(0).reg();
3196 ASSERT(left == result); 3084 ASSERT(left == result);
3197 Label* deopt = NULL; 3085 Label* deopt = NULL;
3198 if (CanDeoptimize()) { 3086 if (CanDeoptimize()) {
3199 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); 3087 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
3200 } 3088 }
3201 3089
3202 if (locs()->in(1).IsConstant()) { 3090 if (locs()->in(1).IsConstant()) {
3203 const Object& constant = locs()->in(1).constant(); 3091 const Object& constant = locs()->in(1).constant();
3204 ASSERT(constant.IsSmi()); 3092 ASSERT(constant.IsSmi());
3205 const intptr_t value = Smi::Cast(constant).Value(); 3093 const intptr_t value = Smi::Cast(constant).Value();
3206 switch (op_kind()) { 3094 switch (op_kind()) {
3207 case Token::kADD: 3095 case Token::kADD:
3208 case Token::kSUB: 3096 case Token::kSUB:
3209 case Token::kMUL: 3097 case Token::kMUL:
3210 case Token::kBIT_AND: 3098 case Token::kBIT_AND:
3211 case Token::kBIT_OR: 3099 case Token::kBIT_OR:
3212 case Token::kBIT_XOR: 3100 case Token::kBIT_XOR:
3213 EmitIntegerArithmetic(compiler, op_kind(), left, Immediate(value), 3101 EmitIntegerArithmetic(compiler, op_kind(), left, Immediate(value),
3214 deopt); 3102 deopt);
3215 break; 3103 break;
3216 3104
3217
3218 case Token::kTRUNCDIV: { 3105 case Token::kTRUNCDIV: {
3219 UNREACHABLE(); 3106 UNREACHABLE();
3220 break; 3107 break;
3221 } 3108 }
3222 3109
3223 case Token::kSHR: { 3110 case Token::kSHR: {
3224 // sarl operation masks the count to 5 bits. 3111 // sarl operation masks the count to 5 bits.
3225 const intptr_t kCountLimit = 0x1F; 3112 const intptr_t kCountLimit = 0x1F;
3226 __ sarl(left, Immediate(Utils::Minimum(value, kCountLimit))); 3113 __ sarl(left, Immediate(Utils::Minimum(value, kCountLimit)));
3227 break; 3114 break;
(...skipping 23 matching lines...) Expand all
3251 case Token::kBIT_XOR: 3138 case Token::kBIT_XOR:
3252 EmitIntegerArithmetic(compiler, op_kind(), left, right, deopt); 3139 EmitIntegerArithmetic(compiler, op_kind(), left, right, deopt);
3253 break; 3140 break;
3254 3141
3255 default: 3142 default:
3256 UNREACHABLE(); 3143 UNREACHABLE();
3257 break; 3144 break;
3258 } 3145 }
3259 } 3146 }
3260 3147
3261
3262 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Zone* zone, 3148 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Zone* zone,
3263 bool opt) const { 3149 bool opt) const {
3264 const intptr_t kNumInputs = 2; 3150 const intptr_t kNumInputs = 2;
3265 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; 3151 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
3266 LocationSummary* summary = new (zone) 3152 LocationSummary* summary = new (zone)
3267 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3153 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3268 if (op_kind() == Token::kMUL) { 3154 if (op_kind() == Token::kMUL) {
3269 summary->set_in(0, Location::RegisterLocation(EAX)); 3155 summary->set_in(0, Location::RegisterLocation(EAX));
3270 summary->set_temp(0, Location::RegisterLocation(EDX)); 3156 summary->set_temp(0, Location::RegisterLocation(EDX));
3271 } else { 3157 } else {
3272 summary->set_in(0, Location::RequiresRegister()); 3158 summary->set_in(0, Location::RequiresRegister());
3273 } 3159 }
3274 summary->set_in(1, Location::RequiresRegister()); 3160 summary->set_in(1, Location::RequiresRegister());
3275 summary->set_out(0, Location::SameAsFirstInput()); 3161 summary->set_out(0, Location::SameAsFirstInput());
3276 return summary; 3162 return summary;
3277 } 3163 }
3278 3164
3279
3280 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3165 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3281 Register left = locs()->in(0).reg(); 3166 Register left = locs()->in(0).reg();
3282 Register right = locs()->in(1).reg(); 3167 Register right = locs()->in(1).reg();
3283 Register out = locs()->out(0).reg(); 3168 Register out = locs()->out(0).reg();
3284 ASSERT(out == left); 3169 ASSERT(out == left);
3285 switch (op_kind()) { 3170 switch (op_kind()) {
3286 case Token::kBIT_AND: 3171 case Token::kBIT_AND:
3287 case Token::kBIT_OR: 3172 case Token::kBIT_OR:
3288 case Token::kBIT_XOR: 3173 case Token::kBIT_XOR:
3289 case Token::kADD: 3174 case Token::kADD:
3290 case Token::kSUB: 3175 case Token::kSUB:
3291 EmitIntegerArithmetic(compiler, op_kind(), left, right, NULL); 3176 EmitIntegerArithmetic(compiler, op_kind(), left, right, NULL);
3292 return; 3177 return;
3293 3178
3294 case Token::kMUL: 3179 case Token::kMUL:
3295 __ mull(right); // Result in EDX:EAX. 3180 __ mull(right); // Result in EDX:EAX.
3296 ASSERT(out == EAX); 3181 ASSERT(out == EAX);
3297 ASSERT(locs()->temp(0).reg() == EDX); 3182 ASSERT(locs()->temp(0).reg() == EDX);
3298 break; 3183 break;
3299 default: 3184 default:
3300 UNREACHABLE(); 3185 UNREACHABLE();
3301 } 3186 }
3302 } 3187 }
3303 3188
3304
3305 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone, 3189 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone,
3306 bool opt) const { 3190 bool opt) const {
3307 intptr_t left_cid = left()->Type()->ToCid(); 3191 intptr_t left_cid = left()->Type()->ToCid();
3308 intptr_t right_cid = right()->Type()->ToCid(); 3192 intptr_t right_cid = right()->Type()->ToCid();
3309 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); 3193 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
3310 const intptr_t kNumInputs = 2; 3194 const intptr_t kNumInputs = 2;
3311 const bool need_temp = (left()->definition() != right()->definition()) && 3195 const bool need_temp = (left()->definition() != right()->definition()) &&
3312 (left_cid != kSmiCid) && (right_cid != kSmiCid); 3196 (left_cid != kSmiCid) && (right_cid != kSmiCid);
3313 const intptr_t kNumTemps = need_temp ? 1 : 0; 3197 const intptr_t kNumTemps = need_temp ? 1 : 0;
3314 LocationSummary* summary = new (zone) 3198 LocationSummary* summary = new (zone)
3315 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3199 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3316 summary->set_in(0, Location::RequiresRegister()); 3200 summary->set_in(0, Location::RequiresRegister());
3317 summary->set_in(1, Location::RequiresRegister()); 3201 summary->set_in(1, Location::RequiresRegister());
3318 if (need_temp) summary->set_temp(0, Location::RequiresRegister()); 3202 if (need_temp) summary->set_temp(0, Location::RequiresRegister());
3319 return summary; 3203 return summary;
3320 } 3204 }
3321 3205
3322
3323 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3206 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3324 Label* deopt = 3207 Label* deopt =
3325 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryDoubleOp, 3208 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryDoubleOp,
3326 licm_hoisted_ ? ICData::kHoisted : 0); 3209 licm_hoisted_ ? ICData::kHoisted : 0);
3327 intptr_t left_cid = left()->Type()->ToCid(); 3210 intptr_t left_cid = left()->Type()->ToCid();
3328 intptr_t right_cid = right()->Type()->ToCid(); 3211 intptr_t right_cid = right()->Type()->ToCid();
3329 Register left = locs()->in(0).reg(); 3212 Register left = locs()->in(0).reg();
3330 Register right = locs()->in(1).reg(); 3213 Register right = locs()->in(1).reg();
3331 if (this->left()->definition() == this->right()->definition()) { 3214 if (this->left()->definition() == this->right()->definition()) {
3332 __ testl(left, Immediate(kSmiTagMask)); 3215 __ testl(left, Immediate(kSmiTagMask));
3333 } else if (left_cid == kSmiCid) { 3216 } else if (left_cid == kSmiCid) {
3334 __ testl(right, Immediate(kSmiTagMask)); 3217 __ testl(right, Immediate(kSmiTagMask));
3335 } else if (right_cid == kSmiCid) { 3218 } else if (right_cid == kSmiCid) {
3336 __ testl(left, Immediate(kSmiTagMask)); 3219 __ testl(left, Immediate(kSmiTagMask));
3337 } else { 3220 } else {
3338 Register temp = locs()->temp(0).reg(); 3221 Register temp = locs()->temp(0).reg();
3339 __ movl(temp, left); 3222 __ movl(temp, left);
3340 __ orl(temp, right); 3223 __ orl(temp, right);
3341 __ testl(temp, Immediate(kSmiTagMask)); 3224 __ testl(temp, Immediate(kSmiTagMask));
3342 } 3225 }
3343 __ j(ZERO, deopt); 3226 __ j(ZERO, deopt);
3344 } 3227 }
3345 3228
3346
3347 LocationSummary* BoxInstr::MakeLocationSummary(Zone* zone, bool opt) const { 3229 LocationSummary* BoxInstr::MakeLocationSummary(Zone* zone, bool opt) const {
3348 const intptr_t kNumInputs = 1; 3230 const intptr_t kNumInputs = 1;
3349 const intptr_t kNumTemps = 1; 3231 const intptr_t kNumTemps = 1;
3350 LocationSummary* summary = new (zone) LocationSummary( 3232 LocationSummary* summary = new (zone) LocationSummary(
3351 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3233 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3352 summary->set_in(0, Location::RequiresFpuRegister()); 3234 summary->set_in(0, Location::RequiresFpuRegister());
3353 summary->set_temp(0, Location::RequiresRegister()); 3235 summary->set_temp(0, Location::RequiresRegister());
3354 summary->set_out(0, Location::RequiresRegister()); 3236 summary->set_out(0, Location::RequiresRegister());
3355 return summary; 3237 return summary;
3356 } 3238 }
3357 3239
3358
3359 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3240 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3360 Register out_reg = locs()->out(0).reg(); 3241 Register out_reg = locs()->out(0).reg();
3361 XmmRegister value = locs()->in(0).fpu_reg(); 3242 XmmRegister value = locs()->in(0).fpu_reg();
3362 3243
3363 BoxAllocationSlowPath::Allocate(compiler, this, 3244 BoxAllocationSlowPath::Allocate(compiler, this,
3364 compiler->BoxClassFor(from_representation()), 3245 compiler->BoxClassFor(from_representation()),
3365 out_reg, locs()->temp(0).reg()); 3246 out_reg, locs()->temp(0).reg());
3366 3247
3367 switch (from_representation()) { 3248 switch (from_representation()) {
3368 case kUnboxedDouble: 3249 case kUnboxedDouble:
3369 __ movsd(FieldAddress(out_reg, ValueOffset()), value); 3250 __ movsd(FieldAddress(out_reg, ValueOffset()), value);
3370 break; 3251 break;
3371 case kUnboxedFloat32x4: 3252 case kUnboxedFloat32x4:
3372 case kUnboxedFloat64x2: 3253 case kUnboxedFloat64x2:
3373 case kUnboxedInt32x4: 3254 case kUnboxedInt32x4:
3374 __ movups(FieldAddress(out_reg, ValueOffset()), value); 3255 __ movups(FieldAddress(out_reg, ValueOffset()), value);
3375 break; 3256 break;
3376 default: 3257 default:
3377 UNREACHABLE(); 3258 UNREACHABLE();
3378 break; 3259 break;
3379 } 3260 }
3380 } 3261 }
3381 3262
3382
3383 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const { 3263 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const {
3384 const bool needs_temp = 3264 const bool needs_temp =
3385 CanDeoptimize() || 3265 CanDeoptimize() ||
3386 (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid)); 3266 (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid));
3387 3267
3388 const intptr_t kNumInputs = 1; 3268 const intptr_t kNumInputs = 1;
3389 const intptr_t kNumTemps = needs_temp ? 1 : 0; 3269 const intptr_t kNumTemps = needs_temp ? 1 : 0;
3390 LocationSummary* summary = new (zone) 3270 LocationSummary* summary = new (zone)
3391 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3271 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3392 summary->set_in(0, Location::RequiresRegister()); 3272 summary->set_in(0, Location::RequiresRegister());
3393 if (needs_temp) { 3273 if (needs_temp) {
3394 summary->set_temp(0, Location::RequiresRegister()); 3274 summary->set_temp(0, Location::RequiresRegister());
3395 } 3275 }
3396 if (representation() == kUnboxedMint) { 3276 if (representation() == kUnboxedMint) {
3397 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), 3277 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
3398 Location::RegisterLocation(EDX))); 3278 Location::RegisterLocation(EDX)));
3399 } else { 3279 } else {
3400 summary->set_out(0, Location::RequiresFpuRegister()); 3280 summary->set_out(0, Location::RequiresFpuRegister());
3401 } 3281 }
3402 return summary; 3282 return summary;
3403 } 3283 }
3404 3284
3405
3406 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { 3285 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
3407 const Register box = locs()->in(0).reg(); 3286 const Register box = locs()->in(0).reg();
3408 3287
3409 switch (representation()) { 3288 switch (representation()) {
3410 case kUnboxedMint: { 3289 case kUnboxedMint: {
3411 PairLocation* result = locs()->out(0).AsPairLocation(); 3290 PairLocation* result = locs()->out(0).AsPairLocation();
3412 __ movl(result->At(0).reg(), FieldAddress(box, ValueOffset())); 3291 __ movl(result->At(0).reg(), FieldAddress(box, ValueOffset()));
3413 __ movl(result->At(1).reg(), 3292 __ movl(result->At(1).reg(),
3414 FieldAddress(box, ValueOffset() + kWordSize)); 3293 FieldAddress(box, ValueOffset() + kWordSize));
3415 break; 3294 break;
(...skipping 12 matching lines...) Expand all
3428 __ movups(result, FieldAddress(box, ValueOffset())); 3307 __ movups(result, FieldAddress(box, ValueOffset()));
3429 break; 3308 break;
3430 } 3309 }
3431 3310
3432 default: 3311 default:
3433 UNREACHABLE(); 3312 UNREACHABLE();
3434 break; 3313 break;
3435 } 3314 }
3436 } 3315 }
3437 3316
3438
3439 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { 3317 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
3440 const Register box = locs()->in(0).reg(); 3318 const Register box = locs()->in(0).reg();
3441 3319
3442 switch (representation()) { 3320 switch (representation()) {
3443 case kUnboxedMint: { 3321 case kUnboxedMint: {
3444 PairLocation* result = locs()->out(0).AsPairLocation(); 3322 PairLocation* result = locs()->out(0).AsPairLocation();
3445 ASSERT(result->At(0).reg() == EAX); 3323 ASSERT(result->At(0).reg() == EAX);
3446 ASSERT(result->At(1).reg() == EDX); 3324 ASSERT(result->At(1).reg() == EDX);
3447 __ movl(EAX, box); 3325 __ movl(EAX, box);
3448 __ SmiUntag(EAX); 3326 __ SmiUntag(EAX);
3449 __ cdq(); 3327 __ cdq();
3450 break; 3328 break;
3451 } 3329 }
3452 3330
3453 case kUnboxedDouble: { 3331 case kUnboxedDouble: {
3454 const Register temp = locs()->temp(0).reg(); 3332 const Register temp = locs()->temp(0).reg();
3455 const FpuRegister result = locs()->out(0).fpu_reg(); 3333 const FpuRegister result = locs()->out(0).fpu_reg();
3456 __ movl(temp, box); 3334 __ movl(temp, box);
3457 __ SmiUntag(temp); 3335 __ SmiUntag(temp);
3458 __ cvtsi2sd(result, temp); 3336 __ cvtsi2sd(result, temp);
3459 break; 3337 break;
3460 } 3338 }
3461 3339
3462 default: 3340 default:
3463 UNREACHABLE(); 3341 UNREACHABLE();
3464 break; 3342 break;
3465 } 3343 }
3466 } 3344 }
3467 3345
3468
3469 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3346 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3470 const intptr_t value_cid = value()->Type()->ToCid(); 3347 const intptr_t value_cid = value()->Type()->ToCid();
3471 const intptr_t box_cid = BoxCid(); 3348 const intptr_t box_cid = BoxCid();
3472 3349
3473 if (value_cid == box_cid) { 3350 if (value_cid == box_cid) {
3474 EmitLoadFromBox(compiler); 3351 EmitLoadFromBox(compiler);
3475 } else if (CanConvertSmi() && (value_cid == kSmiCid)) { 3352 } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
3476 EmitSmiConversion(compiler); 3353 EmitSmiConversion(compiler);
3477 } else { 3354 } else {
3478 const Register box = locs()->in(0).reg(); 3355 const Register box = locs()->in(0).reg();
(...skipping 20 matching lines...) Expand all
3499 if (is_smi.IsLinked()) { 3376 if (is_smi.IsLinked()) {
3500 Label done; 3377 Label done;
3501 __ jmp(&done); 3378 __ jmp(&done);
3502 __ Bind(&is_smi); 3379 __ Bind(&is_smi);
3503 EmitSmiConversion(compiler); 3380 EmitSmiConversion(compiler);
3504 __ Bind(&done); 3381 __ Bind(&done);
3505 } 3382 }
3506 } 3383 }
3507 } 3384 }
3508 3385
3509
3510 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone, 3386 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone,
3511 bool opt) const { 3387 bool opt) const {
3512 const intptr_t kNumInputs = 1; 3388 const intptr_t kNumInputs = 1;
3513 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; 3389 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
3514 LocationSummary* summary = new (zone) 3390 LocationSummary* summary = new (zone)
3515 LocationSummary(zone, kNumInputs, kNumTemps, 3391 LocationSummary(zone, kNumInputs, kNumTemps,
3516 ValueFitsSmi() ? LocationSummary::kNoCall 3392 ValueFitsSmi() ? LocationSummary::kNoCall
3517 : LocationSummary::kCallOnSlowPath); 3393 : LocationSummary::kCallOnSlowPath);
3518 const bool needs_writable_input = 3394 const bool needs_writable_input =
3519 ValueFitsSmi() || (from_representation() == kUnboxedUint32); 3395 ValueFitsSmi() || (from_representation() == kUnboxedUint32);
3520 summary->set_in(0, needs_writable_input ? Location::RequiresRegister() 3396 summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
3521 : Location::WritableRegister()); 3397 : Location::WritableRegister());
3522 if (!ValueFitsSmi()) { 3398 if (!ValueFitsSmi()) {
3523 summary->set_temp(0, Location::RequiresRegister()); 3399 summary->set_temp(0, Location::RequiresRegister());
3524 } 3400 }
3525 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() 3401 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
3526 : Location::RequiresRegister()); 3402 : Location::RequiresRegister());
3527 return summary; 3403 return summary;
3528 } 3404 }
3529 3405
3530
3531 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3406 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3532 const Register value = locs()->in(0).reg(); 3407 const Register value = locs()->in(0).reg();
3533 const Register out = locs()->out(0).reg(); 3408 const Register out = locs()->out(0).reg();
3534 3409
3535 __ MoveRegister(out, value); 3410 __ MoveRegister(out, value);
3536 __ shll(out, Immediate(kSmiTagSize)); 3411 __ shll(out, Immediate(kSmiTagSize));
3537 if (!ValueFitsSmi()) { 3412 if (!ValueFitsSmi()) {
3538 Label done; 3413 Label done;
3539 ASSERT(value != out); 3414 ASSERT(value != out);
3540 if (from_representation() == kUnboxedInt32) { 3415 if (from_representation() == kUnboxedInt32) {
(...skipping 14 matching lines...) Expand all
3555 __ sarl(value, Immediate(31)); // Sign extend. 3430 __ sarl(value, Immediate(31)); // Sign extend.
3556 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); 3431 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
3557 } else { 3432 } else {
3558 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), 3433 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
3559 Immediate(0)); 3434 Immediate(0));
3560 } 3435 }
3561 __ Bind(&done); 3436 __ Bind(&done);
3562 } 3437 }
3563 } 3438 }
3564 3439
3565
3566 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone, 3440 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone,
3567 bool opt) const { 3441 bool opt) const {
3568 const intptr_t kNumInputs = 1; 3442 const intptr_t kNumInputs = 1;
3569 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; 3443 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
3570 LocationSummary* summary = new (zone) 3444 LocationSummary* summary = new (zone)
3571 LocationSummary(zone, kNumInputs, kNumTemps, 3445 LocationSummary(zone, kNumInputs, kNumTemps,
3572 ValueFitsSmi() ? LocationSummary::kNoCall 3446 ValueFitsSmi() ? LocationSummary::kNoCall
3573 : LocationSummary::kCallOnSlowPath); 3447 : LocationSummary::kCallOnSlowPath);
3574 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 3448 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
3575 Location::RequiresRegister())); 3449 Location::RequiresRegister()));
3576 if (!ValueFitsSmi()) { 3450 if (!ValueFitsSmi()) {
3577 summary->set_temp(0, Location::RequiresRegister()); 3451 summary->set_temp(0, Location::RequiresRegister());
3578 } 3452 }
3579 summary->set_out(0, Location::RequiresRegister()); 3453 summary->set_out(0, Location::RequiresRegister());
3580 return summary; 3454 return summary;
3581 } 3455 }
3582 3456
3583
3584 void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3457 void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3585 if (ValueFitsSmi()) { 3458 if (ValueFitsSmi()) {
3586 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 3459 PairLocation* value_pair = locs()->in(0).AsPairLocation();
3587 Register value_lo = value_pair->At(0).reg(); 3460 Register value_lo = value_pair->At(0).reg();
3588 Register out_reg = locs()->out(0).reg(); 3461 Register out_reg = locs()->out(0).reg();
3589 __ movl(out_reg, value_lo); 3462 __ movl(out_reg, value_lo);
3590 __ SmiTag(out_reg); 3463 __ SmiTag(out_reg);
3591 return; 3464 return;
3592 } 3465 }
3593 3466
(...skipping 27 matching lines...) Expand all
3621 // 3. Restore lower half of input before using it. 3494 // 3. Restore lower half of input before using it.
3622 __ subl(value_lo, Immediate(0x40000000)); 3495 __ subl(value_lo, Immediate(0x40000000));
3623 3496
3624 BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), 3497 BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
3625 out_reg, locs()->temp(0).reg()); 3498 out_reg, locs()->temp(0).reg());
3626 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); 3499 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo);
3627 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); 3500 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi);
3628 __ Bind(&done); 3501 __ Bind(&done);
3629 } 3502 }
3630 3503
3631
3632 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone, 3504 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,
3633 bool opt) const { 3505 bool opt) const {
3634 const intptr_t value_cid = value()->Type()->ToCid(); 3506 const intptr_t value_cid = value()->Type()->ToCid();
3635 const intptr_t kNumInputs = 1; 3507 const intptr_t kNumInputs = 1;
3636 intptr_t kNumTemps = 0; 3508 intptr_t kNumTemps = 0;
3637 3509
3638 if (CanDeoptimize()) { 3510 if (CanDeoptimize()) {
3639 if ((value_cid != kSmiCid) && (value_cid != kMintCid) && !is_truncating()) { 3511 if ((value_cid != kSmiCid) && (value_cid != kMintCid) && !is_truncating()) {
3640 kNumTemps = 2; 3512 kNumTemps = 2;
3641 } else { 3513 } else {
3642 kNumTemps = 1; 3514 kNumTemps = 1;
3643 } 3515 }
3644 } 3516 }
3645 3517
3646 LocationSummary* summary = new (zone) 3518 LocationSummary* summary = new (zone)
3647 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3519 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3648 summary->set_in(0, Location::RequiresRegister()); 3520 summary->set_in(0, Location::RequiresRegister());
3649 for (int i = 0; i < kNumTemps; i++) { 3521 for (int i = 0; i < kNumTemps; i++) {
3650 summary->set_temp(i, Location::RequiresRegister()); 3522 summary->set_temp(i, Location::RequiresRegister());
3651 } 3523 }
3652 summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) 3524 summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid))
3653 ? Location::SameAsFirstInput() 3525 ? Location::SameAsFirstInput()
3654 : Location::RequiresRegister()); 3526 : Location::RequiresRegister());
3655 return summary; 3527 return summary;
3656 } 3528 }
3657 3529
3658
3659 static void LoadInt32FromMint(FlowGraphCompiler* compiler, 3530 static void LoadInt32FromMint(FlowGraphCompiler* compiler,
3660 Register result, 3531 Register result,
3661 const Address& lo, 3532 const Address& lo,
3662 const Address& hi, 3533 const Address& hi,
3663 Register temp, 3534 Register temp,
3664 Label* deopt) { 3535 Label* deopt) {
3665 __ movl(result, lo); 3536 __ movl(result, lo);
3666 if (deopt != NULL) { 3537 if (deopt != NULL) {
3667 ASSERT(temp != result); 3538 ASSERT(temp != result);
3668 __ movl(temp, result); 3539 __ movl(temp, result);
3669 __ sarl(temp, Immediate(31)); 3540 __ sarl(temp, Immediate(31));
3670 __ cmpl(temp, hi); 3541 __ cmpl(temp, hi);
3671 __ j(NOT_EQUAL, deopt); 3542 __ j(NOT_EQUAL, deopt);
3672 } 3543 }
3673 } 3544 }
3674 3545
3675
3676 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3546 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3677 const intptr_t value_cid = value()->Type()->ToCid(); 3547 const intptr_t value_cid = value()->Type()->ToCid();
3678 Register value = locs()->in(0).reg(); 3548 Register value = locs()->in(0).reg();
3679 const Register result = locs()->out(0).reg(); 3549 const Register result = locs()->out(0).reg();
3680 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; 3550 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister;
3681 Label* deopt = 3551 Label* deopt = CanDeoptimize() ? compiler->AddDeoptStub(
3682 CanDeoptimize() 3552 GetDeoptId(), ICData::kDeoptUnboxInteger)
3683 ? compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) 3553 : NULL;
3684 : NULL;
3685 Label* out_of_range = !is_truncating() ? deopt : NULL; 3554 Label* out_of_range = !is_truncating() ? deopt : NULL;
3686 3555
3687 const intptr_t lo_offset = Mint::value_offset(); 3556 const intptr_t lo_offset = Mint::value_offset();
3688 const intptr_t hi_offset = Mint::value_offset() + kWordSize; 3557 const intptr_t hi_offset = Mint::value_offset() + kWordSize;
3689 3558
3690 if (value_cid == kSmiCid) { 3559 if (value_cid == kSmiCid) {
3691 ASSERT(value == result); 3560 ASSERT(value == result);
3692 __ SmiUntag(value); 3561 __ SmiUntag(value);
3693 } else if (value_cid == kMintCid) { 3562 } else if (value_cid == kMintCid) {
3694 ASSERT((value != result) || (out_of_range == NULL)); 3563 ASSERT((value != result) || (out_of_range == NULL));
(...skipping 15 matching lines...) Expand all
3710 Register value_temp = locs()->temp(1).reg(); 3579 Register value_temp = locs()->temp(1).reg();
3711 __ movl(value_temp, value); 3580 __ movl(value_temp, value);
3712 value = value_temp; 3581 value = value_temp;
3713 } 3582 }
3714 LoadInt32FromMint(compiler, result, Address(value, TIMES_2, lo_offset), 3583 LoadInt32FromMint(compiler, result, Address(value, TIMES_2, lo_offset),
3715 Address(value, TIMES_2, hi_offset), temp, out_of_range); 3584 Address(value, TIMES_2, hi_offset), temp, out_of_range);
3716 __ Bind(&done); 3585 __ Bind(&done);
3717 } 3586 }
3718 } 3587 }
3719 3588
3720
3721 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone, 3589 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone,
3722 bool opt) const { 3590 bool opt) const {
3723 const bool might_box = (representation() == kTagged) && !can_pack_into_smi(); 3591 const bool might_box = (representation() == kTagged) && !can_pack_into_smi();
3724 const intptr_t kNumInputs = 2; 3592 const intptr_t kNumInputs = 2;
3725 const intptr_t kNumTemps = might_box ? 2 : 0; 3593 const intptr_t kNumTemps = might_box ? 2 : 0;
3726 LocationSummary* summary = new (zone) LocationSummary( 3594 LocationSummary* summary = new (zone) LocationSummary(
3727 zone, kNumInputs, kNumTemps, 3595 zone, kNumInputs, kNumTemps,
3728 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall); 3596 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall);
3729 summary->set_in(0, Location::RequiresRegister()); 3597 summary->set_in(0, Location::RequiresRegister());
3730 // The smi index is either untagged (element size == 1), or it is left smi 3598 // The smi index is either untagged (element size == 1), or it is left smi
3731 // tagged (for all element sizes > 1). 3599 // tagged (for all element sizes > 1).
3732 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister() 3600 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister()
3733 : Location::RequiresRegister()); 3601 : Location::RequiresRegister());
3734 if (might_box) { 3602 if (might_box) {
3735 summary->set_temp(0, Location::RequiresRegister()); 3603 summary->set_temp(0, Location::RequiresRegister());
3736 summary->set_temp(1, Location::RequiresRegister()); 3604 summary->set_temp(1, Location::RequiresRegister());
3737 } 3605 }
3738 3606
3739 if (representation() == kUnboxedMint) { 3607 if (representation() == kUnboxedMint) {
3740 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 3608 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
3741 Location::RequiresRegister())); 3609 Location::RequiresRegister()));
3742 } else { 3610 } else {
3743 ASSERT(representation() == kTagged); 3611 ASSERT(representation() == kTagged);
3744 summary->set_out(0, Location::RequiresRegister()); 3612 summary->set_out(0, Location::RequiresRegister());
3745 } 3613 }
3746 3614
3747 return summary; 3615 return summary;
3748 } 3616 }
3749 3617
3750
3751 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3618 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3752 // The string register points to the backing store for external strings. 3619 // The string register points to the backing store for external strings.
3753 const Register str = locs()->in(0).reg(); 3620 const Register str = locs()->in(0).reg();
3754 const Location index = locs()->in(1); 3621 const Location index = locs()->in(1);
3755 3622
3756 Address element_address = Assembler::ElementAddressForRegIndex( 3623 Address element_address = Assembler::ElementAddressForRegIndex(
3757 IsExternal(), class_id(), index_scale(), str, index.reg()); 3624 IsExternal(), class_id(), index_scale(), str, index.reg());
3758 3625
3759 if ((index_scale() == 1)) { 3626 if ((index_scale() == 1)) {
3760 __ SmiUntag(index.reg()); 3627 __ SmiUntag(index.reg());
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3839 BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), 3706 BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
3840 result, temp2); 3707 result, temp2);
3841 __ movl(FieldAddress(result, Mint::value_offset()), temp); 3708 __ movl(FieldAddress(result, Mint::value_offset()), temp);
3842 __ movl(FieldAddress(result, Mint::value_offset() + kWordSize), 3709 __ movl(FieldAddress(result, Mint::value_offset() + kWordSize),
3843 Immediate(0)); 3710 Immediate(0));
3844 __ Bind(&done); 3711 __ Bind(&done);
3845 } 3712 }
3846 } 3713 }
3847 } 3714 }
3848 3715
3849
3850 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Zone* zone, 3716 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
3851 bool opt) const { 3717 bool opt) const {
3852 const intptr_t kNumInputs = 2; 3718 const intptr_t kNumInputs = 2;
3853 const intptr_t kNumTemps = 0; 3719 const intptr_t kNumTemps = 0;
3854 LocationSummary* summary = new (zone) 3720 LocationSummary* summary = new (zone)
3855 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3721 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3856 summary->set_in(0, Location::RequiresFpuRegister()); 3722 summary->set_in(0, Location::RequiresFpuRegister());
3857 summary->set_in(1, Location::RequiresFpuRegister()); 3723 summary->set_in(1, Location::RequiresFpuRegister());
3858 summary->set_out(0, Location::SameAsFirstInput()); 3724 summary->set_out(0, Location::SameAsFirstInput());
3859 return summary; 3725 return summary;
3860 } 3726 }
3861 3727
3862
3863 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3728 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3864 XmmRegister left = locs()->in(0).fpu_reg(); 3729 XmmRegister left = locs()->in(0).fpu_reg();
3865 XmmRegister right = locs()->in(1).fpu_reg(); 3730 XmmRegister right = locs()->in(1).fpu_reg();
3866 3731
3867 ASSERT(locs()->out(0).fpu_reg() == left); 3732 ASSERT(locs()->out(0).fpu_reg() == left);
3868 3733
3869 switch (op_kind()) { 3734 switch (op_kind()) {
3870 case Token::kADD: 3735 case Token::kADD:
3871 __ addsd(left, right); 3736 __ addsd(left, right);
3872 break; 3737 break;
3873 case Token::kSUB: 3738 case Token::kSUB:
3874 __ subsd(left, right); 3739 __ subsd(left, right);
3875 break; 3740 break;
3876 case Token::kMUL: 3741 case Token::kMUL:
3877 __ mulsd(left, right); 3742 __ mulsd(left, right);
3878 break; 3743 break;
3879 case Token::kDIV: 3744 case Token::kDIV:
3880 __ divsd(left, right); 3745 __ divsd(left, right);
3881 break; 3746 break;
3882 default: 3747 default:
3883 UNREACHABLE(); 3748 UNREACHABLE();
3884 } 3749 }
3885 } 3750 }
3886 3751
3887
3888 LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone, 3752 LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
3889 bool opt) const { 3753 bool opt) const {
3890 const intptr_t kNumInputs = 1; 3754 const intptr_t kNumInputs = 1;
3891 const intptr_t kNumTemps = 3755 const intptr_t kNumTemps =
3892 (op_kind() == MethodRecognizer::kDouble_getIsInfinite) ? 1 : 0; 3756 (op_kind() == MethodRecognizer::kDouble_getIsInfinite) ? 1 : 0;
3893 LocationSummary* summary = new (zone) 3757 LocationSummary* summary = new (zone)
3894 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3758 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3895 summary->set_in(0, Location::RequiresFpuRegister()); 3759 summary->set_in(0, Location::RequiresFpuRegister());
3896 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) { 3760 if (op_kind() == MethodRecognizer::kDouble_getIsInfinite) {
3897 summary->set_temp(0, Location::RequiresRegister()); 3761 summary->set_temp(0, Location::RequiresRegister());
3898 } 3762 }
3899 summary->set_out(0, Location::RequiresRegister()); 3763 summary->set_out(0, Location::RequiresRegister());
3900 return summary; 3764 return summary;
3901 } 3765 }
3902 3766
3903
3904 Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 3767 Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
3905 BranchLabels labels) { 3768 BranchLabels labels) {
3906 ASSERT(compiler->is_optimizing()); 3769 ASSERT(compiler->is_optimizing());
3907 const XmmRegister value = locs()->in(0).fpu_reg(); 3770 const XmmRegister value = locs()->in(0).fpu_reg();
3908 const bool is_negated = kind() != Token::kEQ; 3771 const bool is_negated = kind() != Token::kEQ;
3909 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) { 3772 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) {
3910 Label is_nan; 3773 Label is_nan;
3911 __ comisd(value, value); 3774 __ comisd(value, value);
3912 return is_negated ? PARITY_ODD : PARITY_EVEN; 3775 return is_negated ? PARITY_ODD : PARITY_EVEN;
3913 } else { 3776 } else {
(...skipping 13 matching lines...) Expand all
3927 __ movl(temp, Address(ESP, kWordSize)); 3790 __ movl(temp, Address(ESP, kWordSize));
3928 __ AddImmediate(ESP, Immediate(kDoubleSize)); 3791 __ AddImmediate(ESP, Immediate(kDoubleSize));
3929 // Mask off sign bit. 3792 // Mask off sign bit.
3930 __ andl(temp, Immediate(0x7FFFFFFF)); 3793 __ andl(temp, Immediate(0x7FFFFFFF));
3931 // Compare with +infinity. 3794 // Compare with +infinity.
3932 __ cmpl(temp, Immediate(0x7FF00000)); 3795 __ cmpl(temp, Immediate(0x7FF00000));
3933 return is_negated ? NOT_EQUAL : EQUAL; 3796 return is_negated ? NOT_EQUAL : EQUAL;
3934 } 3797 }
3935 } 3798 }
3936 3799
3937
3938 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, 3800 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone,
3939 bool opt) const { 3801 bool opt) const {
3940 const intptr_t kNumInputs = 2; 3802 const intptr_t kNumInputs = 2;
3941 const intptr_t kNumTemps = 0; 3803 const intptr_t kNumTemps = 0;
3942 LocationSummary* summary = new (zone) 3804 LocationSummary* summary = new (zone)
3943 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3805 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3944 summary->set_in(0, Location::RequiresFpuRegister()); 3806 summary->set_in(0, Location::RequiresFpuRegister());
3945 summary->set_in(1, Location::RequiresFpuRegister()); 3807 summary->set_in(1, Location::RequiresFpuRegister());
3946 summary->set_out(0, Location::SameAsFirstInput()); 3808 summary->set_out(0, Location::SameAsFirstInput());
3947 return summary; 3809 return summary;
3948 } 3810 }
3949 3811
3950
3951 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3812 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3952 XmmRegister left = locs()->in(0).fpu_reg(); 3813 XmmRegister left = locs()->in(0).fpu_reg();
3953 XmmRegister right = locs()->in(1).fpu_reg(); 3814 XmmRegister right = locs()->in(1).fpu_reg();
3954 3815
3955 ASSERT(locs()->out(0).fpu_reg() == left); 3816 ASSERT(locs()->out(0).fpu_reg() == left);
3956 3817
3957 switch (op_kind()) { 3818 switch (op_kind()) {
3958 case Token::kADD: 3819 case Token::kADD:
3959 __ addps(left, right); 3820 __ addps(left, right);
3960 break; 3821 break;
3961 case Token::kSUB: 3822 case Token::kSUB:
3962 __ subps(left, right); 3823 __ subps(left, right);
3963 break; 3824 break;
3964 case Token::kMUL: 3825 case Token::kMUL:
3965 __ mulps(left, right); 3826 __ mulps(left, right);
3966 break; 3827 break;
3967 case Token::kDIV: 3828 case Token::kDIV:
3968 __ divps(left, right); 3829 __ divps(left, right);
3969 break; 3830 break;
3970 default: 3831 default:
3971 UNREACHABLE(); 3832 UNREACHABLE();
3972 } 3833 }
3973 } 3834 }
3974 3835
3975
3976 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(Zone* zone, 3836 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(Zone* zone,
3977 bool opt) const { 3837 bool opt) const {
3978 const intptr_t kNumInputs = 2; 3838 const intptr_t kNumInputs = 2;
3979 const intptr_t kNumTemps = 0; 3839 const intptr_t kNumTemps = 0;
3980 LocationSummary* summary = new (zone) 3840 LocationSummary* summary = new (zone)
3981 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3841 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3982 summary->set_in(0, Location::RequiresFpuRegister()); 3842 summary->set_in(0, Location::RequiresFpuRegister());
3983 summary->set_in(1, Location::RequiresFpuRegister()); 3843 summary->set_in(1, Location::RequiresFpuRegister());
3984 summary->set_out(0, Location::SameAsFirstInput()); 3844 summary->set_out(0, Location::SameAsFirstInput());
3985 return summary; 3845 return summary;
3986 } 3846 }
3987 3847
3988
3989 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3848 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3990 XmmRegister left = locs()->in(0).fpu_reg(); 3849 XmmRegister left = locs()->in(0).fpu_reg();
3991 XmmRegister right = locs()->in(1).fpu_reg(); 3850 XmmRegister right = locs()->in(1).fpu_reg();
3992 3851
3993 ASSERT(locs()->out(0).fpu_reg() == left); 3852 ASSERT(locs()->out(0).fpu_reg() == left);
3994 3853
3995 switch (op_kind()) { 3854 switch (op_kind()) {
3996 case Token::kADD: 3855 case Token::kADD:
3997 __ addpd(left, right); 3856 __ addpd(left, right);
3998 break; 3857 break;
3999 case Token::kSUB: 3858 case Token::kSUB:
4000 __ subpd(left, right); 3859 __ subpd(left, right);
4001 break; 3860 break;
4002 case Token::kMUL: 3861 case Token::kMUL:
4003 __ mulpd(left, right); 3862 __ mulpd(left, right);
4004 break; 3863 break;
4005 case Token::kDIV: 3864 case Token::kDIV:
4006 __ divpd(left, right); 3865 __ divpd(left, right);
4007 break; 3866 break;
4008 default: 3867 default:
4009 UNREACHABLE(); 3868 UNREACHABLE();
4010 } 3869 }
4011 } 3870 }
4012 3871
4013
4014 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(Zone* zone, 3872 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(Zone* zone,
4015 bool opt) const { 3873 bool opt) const {
4016 const intptr_t kNumInputs = 1; 3874 const intptr_t kNumInputs = 1;
4017 const intptr_t kNumTemps = 0; 3875 const intptr_t kNumTemps = 0;
4018 LocationSummary* summary = new (zone) 3876 LocationSummary* summary = new (zone)
4019 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3877 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4020 summary->set_in(0, Location::RequiresFpuRegister()); 3878 summary->set_in(0, Location::RequiresFpuRegister());
4021 summary->set_out(0, Location::SameAsFirstInput()); 3879 summary->set_out(0, Location::SameAsFirstInput());
4022 return summary; 3880 return summary;
4023 } 3881 }
4024 3882
4025
4026 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3883 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4027 XmmRegister value = locs()->in(0).fpu_reg(); 3884 XmmRegister value = locs()->in(0).fpu_reg();
4028 3885
4029 ASSERT(locs()->out(0).fpu_reg() == value); 3886 ASSERT(locs()->out(0).fpu_reg() == value);
4030 3887
4031 switch (op_kind()) { 3888 switch (op_kind()) {
4032 case MethodRecognizer::kFloat32x4ShuffleX: 3889 case MethodRecognizer::kFloat32x4ShuffleX:
4033 // Shuffle not necessary. 3890 // Shuffle not necessary.
4034 __ cvtss2sd(value, value); 3891 __ cvtss2sd(value, value);
4035 break; 3892 break;
(...skipping 11 matching lines...) Expand all
4047 break; 3904 break;
4048 case MethodRecognizer::kFloat32x4Shuffle: 3905 case MethodRecognizer::kFloat32x4Shuffle:
4049 case MethodRecognizer::kInt32x4Shuffle: 3906 case MethodRecognizer::kInt32x4Shuffle:
4050 __ shufps(value, value, Immediate(mask_)); 3907 __ shufps(value, value, Immediate(mask_));
4051 break; 3908 break;
4052 default: 3909 default:
4053 UNREACHABLE(); 3910 UNREACHABLE();
4054 } 3911 }
4055 } 3912 }
4056 3913
4057
4058 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(Zone* zone, 3914 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(Zone* zone,
4059 bool opt) const { 3915 bool opt) const {
4060 const intptr_t kNumInputs = 2; 3916 const intptr_t kNumInputs = 2;
4061 const intptr_t kNumTemps = 0; 3917 const intptr_t kNumTemps = 0;
4062 LocationSummary* summary = new (zone) 3918 LocationSummary* summary = new (zone)
4063 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3919 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4064 summary->set_in(0, Location::RequiresFpuRegister()); 3920 summary->set_in(0, Location::RequiresFpuRegister());
4065 summary->set_in(1, Location::RequiresFpuRegister()); 3921 summary->set_in(1, Location::RequiresFpuRegister());
4066 summary->set_out(0, Location::SameAsFirstInput()); 3922 summary->set_out(0, Location::SameAsFirstInput());
4067 return summary; 3923 return summary;
4068 } 3924 }
4069 3925
4070
4071 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3926 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4072 XmmRegister left = locs()->in(0).fpu_reg(); 3927 XmmRegister left = locs()->in(0).fpu_reg();
4073 XmmRegister right = locs()->in(1).fpu_reg(); 3928 XmmRegister right = locs()->in(1).fpu_reg();
4074 3929
4075 ASSERT(locs()->out(0).fpu_reg() == left); 3930 ASSERT(locs()->out(0).fpu_reg() == left);
4076 switch (op_kind()) { 3931 switch (op_kind()) {
4077 case MethodRecognizer::kFloat32x4ShuffleMix: 3932 case MethodRecognizer::kFloat32x4ShuffleMix:
4078 case MethodRecognizer::kInt32x4ShuffleMix: 3933 case MethodRecognizer::kInt32x4ShuffleMix:
4079 __ shufps(left, right, Immediate(mask_)); 3934 __ shufps(left, right, Immediate(mask_));
4080 break; 3935 break;
4081 default: 3936 default:
4082 UNREACHABLE(); 3937 UNREACHABLE();
4083 } 3938 }
4084 } 3939 }
4085 3940
4086
4087 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(Zone* zone, 3941 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(Zone* zone,
4088 bool opt) const { 3942 bool opt) const {
4089 const intptr_t kNumInputs = 1; 3943 const intptr_t kNumInputs = 1;
4090 const intptr_t kNumTemps = 0; 3944 const intptr_t kNumTemps = 0;
4091 LocationSummary* summary = new (zone) 3945 LocationSummary* summary = new (zone)
4092 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3946 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4093 summary->set_in(0, Location::RequiresFpuRegister()); 3947 summary->set_in(0, Location::RequiresFpuRegister());
4094 summary->set_out(0, Location::RequiresRegister()); 3948 summary->set_out(0, Location::RequiresRegister());
4095 return summary; 3949 return summary;
4096 } 3950 }
4097 3951
4098
4099 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3952 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4100 XmmRegister value = locs()->in(0).fpu_reg(); 3953 XmmRegister value = locs()->in(0).fpu_reg();
4101 Register out = locs()->out(0).reg(); 3954 Register out = locs()->out(0).reg();
4102 3955
4103 __ movmskps(out, value); 3956 __ movmskps(out, value);
4104 __ SmiTag(out); 3957 __ SmiTag(out);
4105 } 3958 }
4106 3959
4107
4108 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( 3960 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
4109 Zone* zone, 3961 Zone* zone,
4110 bool opt) const { 3962 bool opt) const {
4111 const intptr_t kNumInputs = 4; 3963 const intptr_t kNumInputs = 4;
4112 const intptr_t kNumTemps = 0; 3964 const intptr_t kNumTemps = 0;
4113 LocationSummary* summary = new (zone) 3965 LocationSummary* summary = new (zone)
4114 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3966 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4115 summary->set_in(0, Location::RequiresFpuRegister()); 3967 summary->set_in(0, Location::RequiresFpuRegister());
4116 summary->set_in(1, Location::RequiresFpuRegister()); 3968 summary->set_in(1, Location::RequiresFpuRegister());
4117 summary->set_in(2, Location::RequiresFpuRegister()); 3969 summary->set_in(2, Location::RequiresFpuRegister());
4118 summary->set_in(3, Location::RequiresFpuRegister()); 3970 summary->set_in(3, Location::RequiresFpuRegister());
4119 summary->set_out(0, Location::SameAsFirstInput()); 3971 summary->set_out(0, Location::SameAsFirstInput());
4120 return summary; 3972 return summary;
4121 } 3973 }
4122 3974
4123
4124 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3975 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4125 XmmRegister v0 = locs()->in(0).fpu_reg(); 3976 XmmRegister v0 = locs()->in(0).fpu_reg();
4126 XmmRegister v1 = locs()->in(1).fpu_reg(); 3977 XmmRegister v1 = locs()->in(1).fpu_reg();
4127 XmmRegister v2 = locs()->in(2).fpu_reg(); 3978 XmmRegister v2 = locs()->in(2).fpu_reg();
4128 XmmRegister v3 = locs()->in(3).fpu_reg(); 3979 XmmRegister v3 = locs()->in(3).fpu_reg();
4129 ASSERT(v0 == locs()->out(0).fpu_reg()); 3980 ASSERT(v0 == locs()->out(0).fpu_reg());
4130 __ subl(ESP, Immediate(16)); 3981 __ subl(ESP, Immediate(16));
4131 __ cvtsd2ss(v0, v0); 3982 __ cvtsd2ss(v0, v0);
4132 __ movss(Address(ESP, 0), v0); 3983 __ movss(Address(ESP, 0), v0);
4133 __ movsd(v0, v1); 3984 __ movsd(v0, v1);
4134 __ cvtsd2ss(v0, v0); 3985 __ cvtsd2ss(v0, v0);
4135 __ movss(Address(ESP, 4), v0); 3986 __ movss(Address(ESP, 4), v0);
4136 __ movsd(v0, v2); 3987 __ movsd(v0, v2);
4137 __ cvtsd2ss(v0, v0); 3988 __ cvtsd2ss(v0, v0);
4138 __ movss(Address(ESP, 8), v0); 3989 __ movss(Address(ESP, 8), v0);
4139 __ movsd(v0, v3); 3990 __ movsd(v0, v3);
4140 __ cvtsd2ss(v0, v0); 3991 __ cvtsd2ss(v0, v0);
4141 __ movss(Address(ESP, 12), v0); 3992 __ movss(Address(ESP, 12), v0);
4142 __ movups(v0, Address(ESP, 0)); 3993 __ movups(v0, Address(ESP, 0));
4143 __ addl(ESP, Immediate(16)); 3994 __ addl(ESP, Immediate(16));
4144 } 3995 }
4145 3996
4146
4147 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(Zone* zone, 3997 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(Zone* zone,
4148 bool opt) const { 3998 bool opt) const {
4149 const intptr_t kNumInputs = 0; 3999 const intptr_t kNumInputs = 0;
4150 const intptr_t kNumTemps = 0; 4000 const intptr_t kNumTemps = 0;
4151 LocationSummary* summary = new (zone) 4001 LocationSummary* summary = new (zone)
4152 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4002 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4153 summary->set_out(0, Location::RequiresFpuRegister()); 4003 summary->set_out(0, Location::RequiresFpuRegister());
4154 return summary; 4004 return summary;
4155 } 4005 }
4156 4006
4157
4158 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4007 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4159 XmmRegister value = locs()->out(0).fpu_reg(); 4008 XmmRegister value = locs()->out(0).fpu_reg();
4160 __ xorps(value, value); 4009 __ xorps(value, value);
4161 } 4010 }
4162 4011
4163
4164 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(Zone* zone, 4012 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(Zone* zone,
4165 bool opt) const { 4013 bool opt) const {
4166 const intptr_t kNumInputs = 1; 4014 const intptr_t kNumInputs = 1;
4167 const intptr_t kNumTemps = 0; 4015 const intptr_t kNumTemps = 0;
4168 LocationSummary* summary = new (zone) 4016 LocationSummary* summary = new (zone)
4169 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4017 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4170 summary->set_in(0, Location::RequiresFpuRegister()); 4018 summary->set_in(0, Location::RequiresFpuRegister());
4171 summary->set_out(0, Location::SameAsFirstInput()); 4019 summary->set_out(0, Location::SameAsFirstInput());
4172 return summary; 4020 return summary;
4173 } 4021 }
4174 4022
4175
4176 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4023 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4177 XmmRegister value = locs()->out(0).fpu_reg(); 4024 XmmRegister value = locs()->out(0).fpu_reg();
4178 ASSERT(locs()->in(0).fpu_reg() == locs()->out(0).fpu_reg()); 4025 ASSERT(locs()->in(0).fpu_reg() == locs()->out(0).fpu_reg());
4179 // Convert to Float32. 4026 // Convert to Float32.
4180 __ cvtsd2ss(value, value); 4027 __ cvtsd2ss(value, value);
4181 // Splat across all lanes. 4028 // Splat across all lanes.
4182 __ shufps(value, value, Immediate(0x00)); 4029 __ shufps(value, value, Immediate(0x00));
4183 } 4030 }
4184 4031
4185
4186 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(Zone* zone, 4032 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(Zone* zone,
4187 bool opt) const { 4033 bool opt) const {
4188 const intptr_t kNumInputs = 2; 4034 const intptr_t kNumInputs = 2;
4189 const intptr_t kNumTemps = 0; 4035 const intptr_t kNumTemps = 0;
4190 LocationSummary* summary = new (zone) 4036 LocationSummary* summary = new (zone)
4191 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4037 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4192 summary->set_in(0, Location::RequiresFpuRegister()); 4038 summary->set_in(0, Location::RequiresFpuRegister());
4193 summary->set_in(1, Location::RequiresFpuRegister()); 4039 summary->set_in(1, Location::RequiresFpuRegister());
4194 summary->set_out(0, Location::SameAsFirstInput()); 4040 summary->set_out(0, Location::SameAsFirstInput());
4195 return summary; 4041 return summary;
4196 } 4042 }
4197 4043
4198
4199 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4044 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4200 XmmRegister left = locs()->in(0).fpu_reg(); 4045 XmmRegister left = locs()->in(0).fpu_reg();
4201 XmmRegister right = locs()->in(1).fpu_reg(); 4046 XmmRegister right = locs()->in(1).fpu_reg();
4202 4047
4203 ASSERT(locs()->out(0).fpu_reg() == left); 4048 ASSERT(locs()->out(0).fpu_reg() == left);
4204 4049
4205 switch (op_kind()) { 4050 switch (op_kind()) {
4206 case MethodRecognizer::kFloat32x4Equal: 4051 case MethodRecognizer::kFloat32x4Equal:
4207 __ cmppseq(left, right); 4052 __ cmppseq(left, right);
4208 break; 4053 break;
(...skipping 11 matching lines...) Expand all
4220 break; 4065 break;
4221 case MethodRecognizer::kFloat32x4LessThanOrEqual: 4066 case MethodRecognizer::kFloat32x4LessThanOrEqual:
4222 __ cmppsle(left, right); 4067 __ cmppsle(left, right);
4223 break; 4068 break;
4224 4069
4225 default: 4070 default:
4226 UNREACHABLE(); 4071 UNREACHABLE();
4227 } 4072 }
4228 } 4073 }
4229 4074
4230
4231 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(Zone* zone, 4075 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(Zone* zone,
4232 bool opt) const { 4076 bool opt) const {
4233 const intptr_t kNumInputs = 2; 4077 const intptr_t kNumInputs = 2;
4234 const intptr_t kNumTemps = 0; 4078 const intptr_t kNumTemps = 0;
4235 LocationSummary* summary = new (zone) 4079 LocationSummary* summary = new (zone)
4236 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4080 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4237 summary->set_in(0, Location::RequiresFpuRegister()); 4081 summary->set_in(0, Location::RequiresFpuRegister());
4238 summary->set_in(1, Location::RequiresFpuRegister()); 4082 summary->set_in(1, Location::RequiresFpuRegister());
4239 summary->set_out(0, Location::SameAsFirstInput()); 4083 summary->set_out(0, Location::SameAsFirstInput());
4240 return summary; 4084 return summary;
4241 } 4085 }
4242 4086
4243
4244 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4087 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4245 XmmRegister left = locs()->in(0).fpu_reg(); 4088 XmmRegister left = locs()->in(0).fpu_reg();
4246 XmmRegister right = locs()->in(1).fpu_reg(); 4089 XmmRegister right = locs()->in(1).fpu_reg();
4247 4090
4248 ASSERT(locs()->out(0).fpu_reg() == left); 4091 ASSERT(locs()->out(0).fpu_reg() == left);
4249 4092
4250 switch (op_kind()) { 4093 switch (op_kind()) {
4251 case MethodRecognizer::kFloat32x4Min: 4094 case MethodRecognizer::kFloat32x4Min:
4252 __ minps(left, right); 4095 __ minps(left, right);
4253 break; 4096 break;
4254 case MethodRecognizer::kFloat32x4Max: 4097 case MethodRecognizer::kFloat32x4Max:
4255 __ maxps(left, right); 4098 __ maxps(left, right);
4256 break; 4099 break;
4257 default: 4100 default:
4258 UNREACHABLE(); 4101 UNREACHABLE();
4259 } 4102 }
4260 } 4103 }
4261 4104
4262
4263 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(Zone* zone, 4105 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(Zone* zone,
4264 bool opt) const { 4106 bool opt) const {
4265 const intptr_t kNumInputs = 2; 4107 const intptr_t kNumInputs = 2;
4266 const intptr_t kNumTemps = 0; 4108 const intptr_t kNumTemps = 0;
4267 LocationSummary* summary = new (zone) 4109 LocationSummary* summary = new (zone)
4268 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4110 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4269 summary->set_in(0, Location::RequiresFpuRegister()); 4111 summary->set_in(0, Location::RequiresFpuRegister());
4270 summary->set_in(1, Location::RequiresFpuRegister()); 4112 summary->set_in(1, Location::RequiresFpuRegister());
4271 summary->set_out(0, Location::SameAsFirstInput()); 4113 summary->set_out(0, Location::SameAsFirstInput());
4272 return summary; 4114 return summary;
4273 } 4115 }
4274 4116
4275
4276 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4117 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4277 XmmRegister left = locs()->in(0).fpu_reg(); 4118 XmmRegister left = locs()->in(0).fpu_reg();
4278 XmmRegister right = locs()->in(1).fpu_reg(); 4119 XmmRegister right = locs()->in(1).fpu_reg();
4279 4120
4280 ASSERT(locs()->out(0).fpu_reg() == left); 4121 ASSERT(locs()->out(0).fpu_reg() == left);
4281 4122
4282 switch (op_kind()) { 4123 switch (op_kind()) {
4283 case MethodRecognizer::kFloat32x4Scale: 4124 case MethodRecognizer::kFloat32x4Scale:
4284 __ cvtsd2ss(left, left); 4125 __ cvtsd2ss(left, left);
4285 __ shufps(left, left, Immediate(0x00)); 4126 __ shufps(left, left, Immediate(0x00));
4286 __ mulps(left, right); 4127 __ mulps(left, right);
4287 break; 4128 break;
4288 default: 4129 default:
4289 UNREACHABLE(); 4130 UNREACHABLE();
4290 } 4131 }
4291 } 4132 }
4292 4133
4293
4294 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(Zone* zone, 4134 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(Zone* zone,
4295 bool opt) const { 4135 bool opt) const {
4296 const intptr_t kNumInputs = 1; 4136 const intptr_t kNumInputs = 1;
4297 const intptr_t kNumTemps = 0; 4137 const intptr_t kNumTemps = 0;
4298 LocationSummary* summary = new (zone) 4138 LocationSummary* summary = new (zone)
4299 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4139 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4300 summary->set_in(0, Location::RequiresFpuRegister()); 4140 summary->set_in(0, Location::RequiresFpuRegister());
4301 summary->set_out(0, Location::SameAsFirstInput()); 4141 summary->set_out(0, Location::SameAsFirstInput());
4302 return summary; 4142 return summary;
4303 } 4143 }
4304 4144
4305
4306 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4145 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4307 XmmRegister left = locs()->in(0).fpu_reg(); 4146 XmmRegister left = locs()->in(0).fpu_reg();
4308 4147
4309 ASSERT(locs()->out(0).fpu_reg() == left); 4148 ASSERT(locs()->out(0).fpu_reg() == left);
4310 4149
4311 switch (op_kind()) { 4150 switch (op_kind()) {
4312 case MethodRecognizer::kFloat32x4Sqrt: 4151 case MethodRecognizer::kFloat32x4Sqrt:
4313 __ sqrtps(left); 4152 __ sqrtps(left);
4314 break; 4153 break;
4315 case MethodRecognizer::kFloat32x4Reciprocal: 4154 case MethodRecognizer::kFloat32x4Reciprocal:
4316 __ reciprocalps(left); 4155 __ reciprocalps(left);
4317 break; 4156 break;
4318 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 4157 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
4319 __ rsqrtps(left); 4158 __ rsqrtps(left);
4320 break; 4159 break;
4321 default: 4160 default:
4322 UNREACHABLE(); 4161 UNREACHABLE();
4323 } 4162 }
4324 } 4163 }
4325 4164
4326
4327 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(Zone* zone, 4165 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(Zone* zone,
4328 bool opt) const { 4166 bool opt) const {
4329 const intptr_t kNumInputs = 1; 4167 const intptr_t kNumInputs = 1;
4330 const intptr_t kNumTemps = 0; 4168 const intptr_t kNumTemps = 0;
4331 LocationSummary* summary = new (zone) 4169 LocationSummary* summary = new (zone)
4332 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4170 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4333 summary->set_in(0, Location::RequiresFpuRegister()); 4171 summary->set_in(0, Location::RequiresFpuRegister());
4334 summary->set_out(0, Location::SameAsFirstInput()); 4172 summary->set_out(0, Location::SameAsFirstInput());
4335 return summary; 4173 return summary;
4336 } 4174 }
4337 4175
4338
4339 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4176 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4340 XmmRegister left = locs()->in(0).fpu_reg(); 4177 XmmRegister left = locs()->in(0).fpu_reg();
4341 4178
4342 ASSERT(locs()->out(0).fpu_reg() == left); 4179 ASSERT(locs()->out(0).fpu_reg() == left);
4343 switch (op_kind()) { 4180 switch (op_kind()) {
4344 case MethodRecognizer::kFloat32x4Negate: 4181 case MethodRecognizer::kFloat32x4Negate:
4345 __ negateps(left); 4182 __ negateps(left);
4346 break; 4183 break;
4347 case MethodRecognizer::kFloat32x4Absolute: 4184 case MethodRecognizer::kFloat32x4Absolute:
4348 __ absps(left); 4185 __ absps(left);
4349 break; 4186 break;
4350 default: 4187 default:
4351 UNREACHABLE(); 4188 UNREACHABLE();
4352 } 4189 }
4353 } 4190 }
4354 4191
4355
4356 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(Zone* zone, 4192 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(Zone* zone,
4357 bool opt) const { 4193 bool opt) const {
4358 const intptr_t kNumInputs = 3; 4194 const intptr_t kNumInputs = 3;
4359 const intptr_t kNumTemps = 0; 4195 const intptr_t kNumTemps = 0;
4360 LocationSummary* summary = new (zone) 4196 LocationSummary* summary = new (zone)
4361 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4197 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4362 summary->set_in(0, Location::RequiresFpuRegister()); 4198 summary->set_in(0, Location::RequiresFpuRegister());
4363 summary->set_in(1, Location::RequiresFpuRegister()); 4199 summary->set_in(1, Location::RequiresFpuRegister());
4364 summary->set_in(2, Location::RequiresFpuRegister()); 4200 summary->set_in(2, Location::RequiresFpuRegister());
4365 summary->set_out(0, Location::SameAsFirstInput()); 4201 summary->set_out(0, Location::SameAsFirstInput());
4366 return summary; 4202 return summary;
4367 } 4203 }
4368 4204
4369
4370 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4205 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4371 XmmRegister left = locs()->in(0).fpu_reg(); 4206 XmmRegister left = locs()->in(0).fpu_reg();
4372 XmmRegister lower = locs()->in(1).fpu_reg(); 4207 XmmRegister lower = locs()->in(1).fpu_reg();
4373 XmmRegister upper = locs()->in(2).fpu_reg(); 4208 XmmRegister upper = locs()->in(2).fpu_reg();
4374 ASSERT(locs()->out(0).fpu_reg() == left); 4209 ASSERT(locs()->out(0).fpu_reg() == left);
4375 __ minps(left, upper); 4210 __ minps(left, upper);
4376 __ maxps(left, lower); 4211 __ maxps(left, lower);
4377 } 4212 }
4378 4213
4379
4380 LocationSummary* Float32x4WithInstr::MakeLocationSummary(Zone* zone, 4214 LocationSummary* Float32x4WithInstr::MakeLocationSummary(Zone* zone,
4381 bool opt) const { 4215 bool opt) const {
4382 const intptr_t kNumInputs = 2; 4216 const intptr_t kNumInputs = 2;
4383 const intptr_t kNumTemps = 0; 4217 const intptr_t kNumTemps = 0;
4384 LocationSummary* summary = new (zone) 4218 LocationSummary* summary = new (zone)
4385 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4219 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4386 summary->set_in(0, Location::RequiresFpuRegister()); 4220 summary->set_in(0, Location::RequiresFpuRegister());
4387 summary->set_in(1, Location::RequiresFpuRegister()); 4221 summary->set_in(1, Location::RequiresFpuRegister());
4388 summary->set_out(0, Location::SameAsFirstInput()); 4222 summary->set_out(0, Location::SameAsFirstInput());
4389 return summary; 4223 return summary;
4390 } 4224 }
4391 4225
4392
4393 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4226 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4394 XmmRegister replacement = locs()->in(0).fpu_reg(); 4227 XmmRegister replacement = locs()->in(0).fpu_reg();
4395 XmmRegister value = locs()->in(1).fpu_reg(); 4228 XmmRegister value = locs()->in(1).fpu_reg();
4396 4229
4397 ASSERT(locs()->out(0).fpu_reg() == replacement); 4230 ASSERT(locs()->out(0).fpu_reg() == replacement);
4398 4231
4399 switch (op_kind()) { 4232 switch (op_kind()) {
4400 case MethodRecognizer::kFloat32x4WithX: 4233 case MethodRecognizer::kFloat32x4WithX:
4401 __ cvtsd2ss(replacement, replacement); 4234 __ cvtsd2ss(replacement, replacement);
4402 __ subl(ESP, Immediate(16)); 4235 __ subl(ESP, Immediate(16));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4439 __ movss(Address(ESP, 12), replacement); 4272 __ movss(Address(ESP, 12), replacement);
4440 // Move updated value into output register. 4273 // Move updated value into output register.
4441 __ movups(replacement, Address(ESP, 0)); 4274 __ movups(replacement, Address(ESP, 0));
4442 __ addl(ESP, Immediate(16)); 4275 __ addl(ESP, Immediate(16));
4443 break; 4276 break;
4444 default: 4277 default:
4445 UNREACHABLE(); 4278 UNREACHABLE();
4446 } 4279 }
4447 } 4280 }
4448 4281
4449
4450 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(Zone* zone, 4282 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(Zone* zone,
4451 bool opt) const { 4283 bool opt) const {
4452 const intptr_t kNumInputs = 1; 4284 const intptr_t kNumInputs = 1;
4453 const intptr_t kNumTemps = 0; 4285 const intptr_t kNumTemps = 0;
4454 LocationSummary* summary = new (zone) 4286 LocationSummary* summary = new (zone)
4455 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4287 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4456 summary->set_in(0, Location::RequiresFpuRegister()); 4288 summary->set_in(0, Location::RequiresFpuRegister());
4457 summary->set_out(0, Location::SameAsFirstInput()); 4289 summary->set_out(0, Location::SameAsFirstInput());
4458 return summary; 4290 return summary;
4459 } 4291 }
4460 4292
4461
4462 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4293 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4463 // NOP. 4294 // NOP.
4464 } 4295 }
4465 4296
4466
4467 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(Zone* zone, 4297 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(Zone* zone,
4468 bool opt) const { 4298 bool opt) const {
4469 const intptr_t kNumInputs = 1; 4299 const intptr_t kNumInputs = 1;
4470 const intptr_t kNumTemps = 0; 4300 const intptr_t kNumTemps = 0;
4471 LocationSummary* summary = new (zone) 4301 LocationSummary* summary = new (zone)
4472 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4302 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4473 summary->set_in(0, Location::RequiresFpuRegister()); 4303 summary->set_in(0, Location::RequiresFpuRegister());
4474 summary->set_out(0, Location::SameAsFirstInput()); 4304 summary->set_out(0, Location::SameAsFirstInput());
4475 return summary; 4305 return summary;
4476 } 4306 }
4477 4307
4478
4479 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4308 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4480 XmmRegister value = locs()->in(0).fpu_reg(); 4309 XmmRegister value = locs()->in(0).fpu_reg();
4481 4310
4482 ASSERT(locs()->out(0).fpu_reg() == value); 4311 ASSERT(locs()->out(0).fpu_reg() == value);
4483 4312
4484 switch (op_kind()) { 4313 switch (op_kind()) {
4485 case MethodRecognizer::kFloat64x2GetX: 4314 case MethodRecognizer::kFloat64x2GetX:
4486 // nop. 4315 // nop.
4487 break; 4316 break;
4488 case MethodRecognizer::kFloat64x2GetY: 4317 case MethodRecognizer::kFloat64x2GetY:
4489 __ shufpd(value, value, Immediate(0x33)); 4318 __ shufpd(value, value, Immediate(0x33));
4490 break; 4319 break;
4491 default: 4320 default:
4492 UNREACHABLE(); 4321 UNREACHABLE();
4493 } 4322 }
4494 } 4323 }
4495 4324
4496
4497 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(Zone* zone, 4325 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(Zone* zone,
4498 bool opt) const { 4326 bool opt) const {
4499 const intptr_t kNumInputs = 0; 4327 const intptr_t kNumInputs = 0;
4500 const intptr_t kNumTemps = 0; 4328 const intptr_t kNumTemps = 0;
4501 LocationSummary* summary = new (zone) 4329 LocationSummary* summary = new (zone)
4502 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4330 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4503 summary->set_out(0, Location::RequiresFpuRegister()); 4331 summary->set_out(0, Location::RequiresFpuRegister());
4504 return summary; 4332 return summary;
4505 } 4333 }
4506 4334
4507
4508 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4335 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4509 XmmRegister value = locs()->out(0).fpu_reg(); 4336 XmmRegister value = locs()->out(0).fpu_reg();
4510 __ xorpd(value, value); 4337 __ xorpd(value, value);
4511 } 4338 }
4512 4339
4513
4514 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(Zone* zone, 4340 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(Zone* zone,
4515 bool opt) const { 4341 bool opt) const {
4516 const intptr_t kNumInputs = 1; 4342 const intptr_t kNumInputs = 1;
4517 const intptr_t kNumTemps = 0; 4343 const intptr_t kNumTemps = 0;
4518 LocationSummary* summary = new (zone) 4344 LocationSummary* summary = new (zone)
4519 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4345 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4520 summary->set_in(0, Location::RequiresFpuRegister()); 4346 summary->set_in(0, Location::RequiresFpuRegister());
4521 summary->set_out(0, Location::SameAsFirstInput()); 4347 summary->set_out(0, Location::SameAsFirstInput());
4522 return summary; 4348 return summary;
4523 } 4349 }
4524 4350
4525
4526 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4351 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4527 XmmRegister value = locs()->out(0).fpu_reg(); 4352 XmmRegister value = locs()->out(0).fpu_reg();
4528 __ shufpd(value, value, Immediate(0x0)); 4353 __ shufpd(value, value, Immediate(0x0));
4529 } 4354 }
4530 4355
4531
4532 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( 4356 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary(
4533 Zone* zone, 4357 Zone* zone,
4534 bool opt) const { 4358 bool opt) const {
4535 const intptr_t kNumInputs = 2; 4359 const intptr_t kNumInputs = 2;
4536 const intptr_t kNumTemps = 0; 4360 const intptr_t kNumTemps = 0;
4537 LocationSummary* summary = new (zone) 4361 LocationSummary* summary = new (zone)
4538 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4362 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4539 summary->set_in(0, Location::RequiresFpuRegister()); 4363 summary->set_in(0, Location::RequiresFpuRegister());
4540 summary->set_in(1, Location::RequiresFpuRegister()); 4364 summary->set_in(1, Location::RequiresFpuRegister());
4541 summary->set_out(0, Location::SameAsFirstInput()); 4365 summary->set_out(0, Location::SameAsFirstInput());
4542 return summary; 4366 return summary;
4543 } 4367 }
4544 4368
4545
4546 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4369 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4547 XmmRegister v0 = locs()->in(0).fpu_reg(); 4370 XmmRegister v0 = locs()->in(0).fpu_reg();
4548 XmmRegister v1 = locs()->in(1).fpu_reg(); 4371 XmmRegister v1 = locs()->in(1).fpu_reg();
4549 ASSERT(v0 == locs()->out(0).fpu_reg()); 4372 ASSERT(v0 == locs()->out(0).fpu_reg());
4550 // shufpd mask 0x0 results in: 4373 // shufpd mask 0x0 results in:
4551 // Lower 64-bits of v0 = Lower 64-bits of v0. 4374 // Lower 64-bits of v0 = Lower 64-bits of v0.
4552 // Upper 64-bits of v0 = Lower 64-bits of v1. 4375 // Upper 64-bits of v0 = Lower 64-bits of v1.
4553 __ shufpd(v0, v1, Immediate(0x0)); 4376 __ shufpd(v0, v1, Immediate(0x0));
4554 } 4377 }
4555 4378
4556
4557 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( 4379 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary(
4558 Zone* zone, 4380 Zone* zone,
4559 bool opt) const { 4381 bool opt) const {
4560 const intptr_t kNumInputs = 1; 4382 const intptr_t kNumInputs = 1;
4561 const intptr_t kNumTemps = 0; 4383 const intptr_t kNumTemps = 0;
4562 LocationSummary* summary = new (zone) 4384 LocationSummary* summary = new (zone)
4563 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4385 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4564 summary->set_in(0, Location::RequiresFpuRegister()); 4386 summary->set_in(0, Location::RequiresFpuRegister());
4565 summary->set_out(0, Location::SameAsFirstInput()); 4387 summary->set_out(0, Location::SameAsFirstInput());
4566 return summary; 4388 return summary;
4567 } 4389 }
4568 4390
4569
4570 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4391 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4571 XmmRegister value = locs()->out(0).fpu_reg(); 4392 XmmRegister value = locs()->out(0).fpu_reg();
4572 __ cvtpd2ps(value, value); 4393 __ cvtpd2ps(value, value);
4573 } 4394 }
4574 4395
4575
4576 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( 4396 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary(
4577 Zone* zone, 4397 Zone* zone,
4578 bool opt) const { 4398 bool opt) const {
4579 const intptr_t kNumInputs = 1; 4399 const intptr_t kNumInputs = 1;
4580 const intptr_t kNumTemps = 0; 4400 const intptr_t kNumTemps = 0;
4581 LocationSummary* summary = new (zone) 4401 LocationSummary* summary = new (zone)
4582 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4402 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4583 summary->set_in(0, Location::RequiresFpuRegister()); 4403 summary->set_in(0, Location::RequiresFpuRegister());
4584 summary->set_out(0, Location::SameAsFirstInput()); 4404 summary->set_out(0, Location::SameAsFirstInput());
4585 return summary; 4405 return summary;
4586 } 4406 }
4587 4407
4588
4589 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4408 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4590 XmmRegister value = locs()->out(0).fpu_reg(); 4409 XmmRegister value = locs()->out(0).fpu_reg();
4591 __ cvtps2pd(value, value); 4410 __ cvtps2pd(value, value);
4592 } 4411 }
4593 4412
4594
4595 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(Zone* zone, 4413 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(Zone* zone,
4596 bool opt) const { 4414 bool opt) const {
4597 const intptr_t kNumInputs = 1; 4415 const intptr_t kNumInputs = 1;
4598 const intptr_t kNumTemps = 0; 4416 const intptr_t kNumTemps = 0;
4599 LocationSummary* summary = new (zone) 4417 LocationSummary* summary = new (zone)
4600 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4418 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4601 summary->set_in(0, Location::RequiresFpuRegister()); 4419 summary->set_in(0, Location::RequiresFpuRegister());
4602 if (representation() == kTagged) { 4420 if (representation() == kTagged) {
4603 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask); 4421 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask);
4604 summary->set_out(0, Location::RequiresRegister()); 4422 summary->set_out(0, Location::RequiresRegister());
4605 } else { 4423 } else {
4606 ASSERT(representation() == kUnboxedFloat64x2); 4424 ASSERT(representation() == kUnboxedFloat64x2);
4607 summary->set_out(0, Location::SameAsFirstInput()); 4425 summary->set_out(0, Location::SameAsFirstInput());
4608 } 4426 }
4609 return summary; 4427 return summary;
4610 } 4428 }
4611 4429
4612
4613 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4430 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4614 XmmRegister left = locs()->in(0).fpu_reg(); 4431 XmmRegister left = locs()->in(0).fpu_reg();
4615 4432
4616 ASSERT((op_kind() == MethodRecognizer::kFloat64x2GetSignMask) || 4433 ASSERT((op_kind() == MethodRecognizer::kFloat64x2GetSignMask) ||
4617 (locs()->out(0).fpu_reg() == left)); 4434 (locs()->out(0).fpu_reg() == left));
4618 4435
4619 switch (op_kind()) { 4436 switch (op_kind()) {
4620 case MethodRecognizer::kFloat64x2Negate: 4437 case MethodRecognizer::kFloat64x2Negate:
4621 __ negatepd(left); 4438 __ negatepd(left);
4622 break; 4439 break;
4623 case MethodRecognizer::kFloat64x2Abs: 4440 case MethodRecognizer::kFloat64x2Abs:
4624 __ abspd(left); 4441 __ abspd(left);
4625 break; 4442 break;
4626 case MethodRecognizer::kFloat64x2Sqrt: 4443 case MethodRecognizer::kFloat64x2Sqrt:
4627 __ sqrtpd(left); 4444 __ sqrtpd(left);
4628 break; 4445 break;
4629 case MethodRecognizer::kFloat64x2GetSignMask: 4446 case MethodRecognizer::kFloat64x2GetSignMask:
4630 __ movmskpd(locs()->out(0).reg(), left); 4447 __ movmskpd(locs()->out(0).reg(), left);
4631 __ SmiTag(locs()->out(0).reg()); 4448 __ SmiTag(locs()->out(0).reg());
4632 break; 4449 break;
4633 default: 4450 default:
4634 UNREACHABLE(); 4451 UNREACHABLE();
4635 } 4452 }
4636 } 4453 }
4637 4454
4638
4639 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(Zone* zone, 4455 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(Zone* zone,
4640 bool opt) const { 4456 bool opt) const {
4641 const intptr_t kNumInputs = 2; 4457 const intptr_t kNumInputs = 2;
4642 const intptr_t kNumTemps = 0; 4458 const intptr_t kNumTemps = 0;
4643 LocationSummary* summary = new (zone) 4459 LocationSummary* summary = new (zone)
4644 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4460 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4645 summary->set_in(0, Location::RequiresFpuRegister()); 4461 summary->set_in(0, Location::RequiresFpuRegister());
4646 summary->set_in(1, Location::RequiresFpuRegister()); 4462 summary->set_in(1, Location::RequiresFpuRegister());
4647 summary->set_out(0, Location::SameAsFirstInput()); 4463 summary->set_out(0, Location::SameAsFirstInput());
4648 return summary; 4464 return summary;
4649 } 4465 }
4650 4466
4651
4652 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4467 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4653 XmmRegister left = locs()->in(0).fpu_reg(); 4468 XmmRegister left = locs()->in(0).fpu_reg();
4654 XmmRegister right = locs()->in(1).fpu_reg(); 4469 XmmRegister right = locs()->in(1).fpu_reg();
4655 ASSERT((locs()->out(0).fpu_reg() == left)); 4470 ASSERT((locs()->out(0).fpu_reg() == left));
4656 4471
4657 switch (op_kind()) { 4472 switch (op_kind()) {
4658 case MethodRecognizer::kFloat64x2Scale: 4473 case MethodRecognizer::kFloat64x2Scale:
4659 __ shufpd(right, right, Immediate(0x00)); 4474 __ shufpd(right, right, Immediate(0x00));
4660 __ mulpd(left, right); 4475 __ mulpd(left, right);
4661 break; 4476 break;
(...skipping 21 matching lines...) Expand all
4683 __ minpd(left, right); 4498 __ minpd(left, right);
4684 break; 4499 break;
4685 case MethodRecognizer::kFloat64x2Max: 4500 case MethodRecognizer::kFloat64x2Max:
4686 __ maxpd(left, right); 4501 __ maxpd(left, right);
4687 break; 4502 break;
4688 default: 4503 default:
4689 UNREACHABLE(); 4504 UNREACHABLE();
4690 } 4505 }
4691 } 4506 }
4692 4507
4693
4694 LocationSummary* Int32x4ConstructorInstr::MakeLocationSummary(Zone* zone, 4508 LocationSummary* Int32x4ConstructorInstr::MakeLocationSummary(Zone* zone,
4695 bool opt) const { 4509 bool opt) const {
4696 const intptr_t kNumInputs = 4; 4510 const intptr_t kNumInputs = 4;
4697 const intptr_t kNumTemps = 0; 4511 const intptr_t kNumTemps = 0;
4698 LocationSummary* summary = new (zone) 4512 LocationSummary* summary = new (zone)
4699 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4513 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4700 summary->set_in(0, Location::RequiresRegister()); 4514 summary->set_in(0, Location::RequiresRegister());
4701 summary->set_in(1, Location::RequiresRegister()); 4515 summary->set_in(1, Location::RequiresRegister());
4702 summary->set_in(2, Location::RequiresRegister()); 4516 summary->set_in(2, Location::RequiresRegister());
4703 summary->set_in(3, Location::RequiresRegister()); 4517 summary->set_in(3, Location::RequiresRegister());
4704 summary->set_out(0, Location::RequiresFpuRegister()); 4518 summary->set_out(0, Location::RequiresFpuRegister());
4705 return summary; 4519 return summary;
4706 } 4520 }
4707 4521
4708
4709 void Int32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4522 void Int32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4710 Register v0 = locs()->in(0).reg(); 4523 Register v0 = locs()->in(0).reg();
4711 Register v1 = locs()->in(1).reg(); 4524 Register v1 = locs()->in(1).reg();
4712 Register v2 = locs()->in(2).reg(); 4525 Register v2 = locs()->in(2).reg();
4713 Register v3 = locs()->in(3).reg(); 4526 Register v3 = locs()->in(3).reg();
4714 XmmRegister result = locs()->out(0).fpu_reg(); 4527 XmmRegister result = locs()->out(0).fpu_reg();
4715 __ subl(ESP, Immediate(4 * kInt32Size)); 4528 __ subl(ESP, Immediate(4 * kInt32Size));
4716 __ movl(Address(ESP, 0 * kInt32Size), v0); 4529 __ movl(Address(ESP, 0 * kInt32Size), v0);
4717 __ movl(Address(ESP, 1 * kInt32Size), v1); 4530 __ movl(Address(ESP, 1 * kInt32Size), v1);
4718 __ movl(Address(ESP, 2 * kInt32Size), v2); 4531 __ movl(Address(ESP, 2 * kInt32Size), v2);
4719 __ movl(Address(ESP, 3 * kInt32Size), v3); 4532 __ movl(Address(ESP, 3 * kInt32Size), v3);
4720 __ movups(result, Address(ESP, 0)); 4533 __ movups(result, Address(ESP, 0));
4721 __ addl(ESP, Immediate(4 * kInt32Size)); 4534 __ addl(ESP, Immediate(4 * kInt32Size));
4722 } 4535 }
4723 4536
4724
4725 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( 4537 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary(
4726 Zone* zone, 4538 Zone* zone,
4727 bool opt) const { 4539 bool opt) const {
4728 const intptr_t kNumInputs = 4; 4540 const intptr_t kNumInputs = 4;
4729 const intptr_t kNumTemps = 0; 4541 const intptr_t kNumTemps = 0;
4730 LocationSummary* summary = new (zone) 4542 LocationSummary* summary = new (zone)
4731 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4543 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4732 summary->set_in(0, Location::RequiresRegister()); 4544 summary->set_in(0, Location::RequiresRegister());
4733 summary->set_in(1, Location::RequiresRegister()); 4545 summary->set_in(1, Location::RequiresRegister());
4734 summary->set_in(2, Location::RequiresRegister()); 4546 summary->set_in(2, Location::RequiresRegister());
4735 summary->set_in(3, Location::RequiresRegister()); 4547 summary->set_in(3, Location::RequiresRegister());
4736 summary->set_out(0, Location::RequiresFpuRegister()); 4548 summary->set_out(0, Location::RequiresFpuRegister());
4737 return summary; 4549 return summary;
4738 } 4550 }
4739 4551
4740
4741 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4552 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4742 Register v0 = locs()->in(0).reg(); 4553 Register v0 = locs()->in(0).reg();
4743 Register v1 = locs()->in(1).reg(); 4554 Register v1 = locs()->in(1).reg();
4744 Register v2 = locs()->in(2).reg(); 4555 Register v2 = locs()->in(2).reg();
4745 Register v3 = locs()->in(3).reg(); 4556 Register v3 = locs()->in(3).reg();
4746 XmmRegister result = locs()->out(0).fpu_reg(); 4557 XmmRegister result = locs()->out(0).fpu_reg();
4747 Label x_false, x_done; 4558 Label x_false, x_done;
4748 Label y_false, y_done; 4559 Label y_false, y_done;
4749 Label z_false, z_done; 4560 Label z_false, z_done;
4750 Label w_false, w_done; 4561 Label w_false, w_done;
(...skipping 27 matching lines...) Expand all
4778 __ movl(Address(ESP, 12), Immediate(0xFFFFFFFF)); 4589 __ movl(Address(ESP, 12), Immediate(0xFFFFFFFF));
4779 __ jmp(&w_done); 4590 __ jmp(&w_done);
4780 __ Bind(&w_false); 4591 __ Bind(&w_false);
4781 __ movl(Address(ESP, 12), Immediate(0x0)); 4592 __ movl(Address(ESP, 12), Immediate(0x0));
4782 __ Bind(&w_done); 4593 __ Bind(&w_done);
4783 4594
4784 __ movups(result, Address(ESP, 0)); 4595 __ movups(result, Address(ESP, 0));
4785 __ addl(ESP, Immediate(16)); 4596 __ addl(ESP, Immediate(16));
4786 } 4597 }
4787 4598
4788
4789 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(Zone* zone, 4599 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(Zone* zone,
4790 bool opt) const { 4600 bool opt) const {
4791 const intptr_t kNumInputs = 1; 4601 const intptr_t kNumInputs = 1;
4792 const intptr_t kNumTemps = 0; 4602 const intptr_t kNumTemps = 0;
4793 LocationSummary* summary = new (zone) 4603 LocationSummary* summary = new (zone)
4794 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4604 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4795 summary->set_in(0, Location::RequiresFpuRegister()); 4605 summary->set_in(0, Location::RequiresFpuRegister());
4796 summary->set_out(0, Location::RequiresRegister()); 4606 summary->set_out(0, Location::RequiresRegister());
4797 return summary; 4607 return summary;
4798 } 4608 }
4799 4609
4800
4801 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4610 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4802 XmmRegister value = locs()->in(0).fpu_reg(); 4611 XmmRegister value = locs()->in(0).fpu_reg();
4803 Register result = locs()->out(0).reg(); 4612 Register result = locs()->out(0).reg();
4804 Label done; 4613 Label done;
4805 Label non_zero; 4614 Label non_zero;
4806 __ subl(ESP, Immediate(16)); 4615 __ subl(ESP, Immediate(16));
4807 // Move value to stack. 4616 // Move value to stack.
4808 __ movups(Address(ESP, 0), value); 4617 __ movups(Address(ESP, 0), value);
4809 switch (op_kind()) { 4618 switch (op_kind()) {
4810 case MethodRecognizer::kInt32x4GetFlagX: 4619 case MethodRecognizer::kInt32x4GetFlagX:
(...skipping 14 matching lines...) Expand all
4825 __ addl(ESP, Immediate(16)); 4634 __ addl(ESP, Immediate(16));
4826 __ testl(result, result); 4635 __ testl(result, result);
4827 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); 4636 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump);
4828 __ LoadObject(result, Bool::False()); 4637 __ LoadObject(result, Bool::False());
4829 __ jmp(&done); 4638 __ jmp(&done);
4830 __ Bind(&non_zero); 4639 __ Bind(&non_zero);
4831 __ LoadObject(result, Bool::True()); 4640 __ LoadObject(result, Bool::True());
4832 __ Bind(&done); 4641 __ Bind(&done);
4833 } 4642 }
4834 4643
4835
4836 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(Zone* zone, 4644 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(Zone* zone,
4837 bool opt) const { 4645 bool opt) const {
4838 const intptr_t kNumInputs = 3; 4646 const intptr_t kNumInputs = 3;
4839 const intptr_t kNumTemps = 1; 4647 const intptr_t kNumTemps = 1;
4840 LocationSummary* summary = new (zone) 4648 LocationSummary* summary = new (zone)
4841 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4649 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4842 summary->set_in(0, Location::RequiresFpuRegister()); 4650 summary->set_in(0, Location::RequiresFpuRegister());
4843 summary->set_in(1, Location::RequiresFpuRegister()); 4651 summary->set_in(1, Location::RequiresFpuRegister());
4844 summary->set_in(2, Location::RequiresFpuRegister()); 4652 summary->set_in(2, Location::RequiresFpuRegister());
4845 summary->set_temp(0, Location::RequiresFpuRegister()); 4653 summary->set_temp(0, Location::RequiresFpuRegister());
4846 summary->set_out(0, Location::SameAsFirstInput()); 4654 summary->set_out(0, Location::SameAsFirstInput());
4847 return summary; 4655 return summary;
4848 } 4656 }
4849 4657
4850
4851 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4658 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4852 XmmRegister mask = locs()->in(0).fpu_reg(); 4659 XmmRegister mask = locs()->in(0).fpu_reg();
4853 XmmRegister trueValue = locs()->in(1).fpu_reg(); 4660 XmmRegister trueValue = locs()->in(1).fpu_reg();
4854 XmmRegister falseValue = locs()->in(2).fpu_reg(); 4661 XmmRegister falseValue = locs()->in(2).fpu_reg();
4855 XmmRegister out = locs()->out(0).fpu_reg(); 4662 XmmRegister out = locs()->out(0).fpu_reg();
4856 XmmRegister temp = locs()->temp(0).fpu_reg(); 4663 XmmRegister temp = locs()->temp(0).fpu_reg();
4857 ASSERT(out == mask); 4664 ASSERT(out == mask);
4858 // Copy mask. 4665 // Copy mask.
4859 __ movaps(temp, mask); 4666 __ movaps(temp, mask);
4860 // Invert it. 4667 // Invert it.
4861 __ notps(temp); 4668 __ notps(temp);
4862 // mask = mask & trueValue. 4669 // mask = mask & trueValue.
4863 __ andps(mask, trueValue); 4670 __ andps(mask, trueValue);
4864 // temp = temp & falseValue. 4671 // temp = temp & falseValue.
4865 __ andps(temp, falseValue); 4672 __ andps(temp, falseValue);
4866 // out = mask | temp. 4673 // out = mask | temp.
4867 __ orps(mask, temp); 4674 __ orps(mask, temp);
4868 } 4675 }
4869 4676
4870
4871 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(Zone* zone, 4677 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(Zone* zone,
4872 bool opt) const { 4678 bool opt) const {
4873 const intptr_t kNumInputs = 2; 4679 const intptr_t kNumInputs = 2;
4874 const intptr_t kNumTemps = 0; 4680 const intptr_t kNumTemps = 0;
4875 LocationSummary* summary = new (zone) 4681 LocationSummary* summary = new (zone)
4876 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4682 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4877 summary->set_in(0, Location::RequiresFpuRegister()); 4683 summary->set_in(0, Location::RequiresFpuRegister());
4878 summary->set_in(1, Location::RequiresRegister()); 4684 summary->set_in(1, Location::RequiresRegister());
4879 summary->set_out(0, Location::SameAsFirstInput()); 4685 summary->set_out(0, Location::SameAsFirstInput());
4880 return summary; 4686 return summary;
4881 } 4687 }
4882 4688
4883
4884 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4689 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4885 XmmRegister mask = locs()->in(0).fpu_reg(); 4690 XmmRegister mask = locs()->in(0).fpu_reg();
4886 Register flag = locs()->in(1).reg(); 4691 Register flag = locs()->in(1).reg();
4887 ASSERT(mask == locs()->out(0).fpu_reg()); 4692 ASSERT(mask == locs()->out(0).fpu_reg());
4888 __ subl(ESP, Immediate(16)); 4693 __ subl(ESP, Immediate(16));
4889 // Copy mask to stack. 4694 // Copy mask to stack.
4890 __ movups(Address(ESP, 0), mask); 4695 __ movups(Address(ESP, 0), mask);
4891 Label falsePath, exitPath; 4696 Label falsePath, exitPath;
4892 __ CompareObject(flag, Bool::True()); 4697 __ CompareObject(flag, Bool::True());
4893 __ j(NOT_EQUAL, &falsePath); 4698 __ j(NOT_EQUAL, &falsePath);
(...skipping 24 matching lines...) Expand all
4918 break; 4723 break;
4919 default: 4724 default:
4920 UNREACHABLE(); 4725 UNREACHABLE();
4921 } 4726 }
4922 __ Bind(&exitPath); 4727 __ Bind(&exitPath);
4923 // Copy mask back to register. 4728 // Copy mask back to register.
4924 __ movups(mask, Address(ESP, 0)); 4729 __ movups(mask, Address(ESP, 0));
4925 __ addl(ESP, Immediate(16)); 4730 __ addl(ESP, Immediate(16));
4926 } 4731 }
4927 4732
4928
4929 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(Zone* zone, 4733 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(Zone* zone,
4930 bool opt) const { 4734 bool opt) const {
4931 const intptr_t kNumInputs = 1; 4735 const intptr_t kNumInputs = 1;
4932 const intptr_t kNumTemps = 0; 4736 const intptr_t kNumTemps = 0;
4933 LocationSummary* summary = new (zone) 4737 LocationSummary* summary = new (zone)
4934 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4738 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4935 summary->set_in(0, Location::RequiresFpuRegister()); 4739 summary->set_in(0, Location::RequiresFpuRegister());
4936 summary->set_out(0, Location::SameAsFirstInput()); 4740 summary->set_out(0, Location::SameAsFirstInput());
4937 return summary; 4741 return summary;
4938 } 4742 }
4939 4743
4940
4941 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4744 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4942 // NOP. 4745 // NOP.
4943 } 4746 }
4944 4747
4945
4946 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(Zone* zone, 4748 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(Zone* zone,
4947 bool opt) const { 4749 bool opt) const {
4948 const intptr_t kNumInputs = 2; 4750 const intptr_t kNumInputs = 2;
4949 const intptr_t kNumTemps = 0; 4751 const intptr_t kNumTemps = 0;
4950 LocationSummary* summary = new (zone) 4752 LocationSummary* summary = new (zone)
4951 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4753 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4952 summary->set_in(0, Location::RequiresFpuRegister()); 4754 summary->set_in(0, Location::RequiresFpuRegister());
4953 summary->set_in(1, Location::RequiresFpuRegister()); 4755 summary->set_in(1, Location::RequiresFpuRegister());
4954 summary->set_out(0, Location::SameAsFirstInput()); 4756 summary->set_out(0, Location::SameAsFirstInput());
4955 return summary; 4757 return summary;
4956 } 4758 }
4957 4759
4958
4959 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4760 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4960 XmmRegister left = locs()->in(0).fpu_reg(); 4761 XmmRegister left = locs()->in(0).fpu_reg();
4961 XmmRegister right = locs()->in(1).fpu_reg(); 4762 XmmRegister right = locs()->in(1).fpu_reg();
4962 ASSERT(left == locs()->out(0).fpu_reg()); 4763 ASSERT(left == locs()->out(0).fpu_reg());
4963 switch (op_kind()) { 4764 switch (op_kind()) {
4964 case Token::kBIT_AND: { 4765 case Token::kBIT_AND: {
4965 __ andps(left, right); 4766 __ andps(left, right);
4966 break; 4767 break;
4967 } 4768 }
4968 case Token::kBIT_OR: { 4769 case Token::kBIT_OR: {
4969 __ orps(left, right); 4770 __ orps(left, right);
4970 break; 4771 break;
4971 } 4772 }
4972 case Token::kBIT_XOR: { 4773 case Token::kBIT_XOR: {
4973 __ xorps(left, right); 4774 __ xorps(left, right);
4974 break; 4775 break;
4975 } 4776 }
4976 case Token::kADD: 4777 case Token::kADD:
4977 __ addpl(left, right); 4778 __ addpl(left, right);
4978 break; 4779 break;
4979 case Token::kSUB: 4780 case Token::kSUB:
4980 __ subpl(left, right); 4781 __ subpl(left, right);
4981 break; 4782 break;
4982 default: 4783 default:
4983 UNREACHABLE(); 4784 UNREACHABLE();
4984 } 4785 }
4985 } 4786 }
4986 4787
4987
4988 LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone, 4788 LocationSummary* MathUnaryInstr::MakeLocationSummary(Zone* zone,
4989 bool opt) const { 4789 bool opt) const {
4990 ASSERT((kind() == MathUnaryInstr::kSqrt) || 4790 ASSERT((kind() == MathUnaryInstr::kSqrt) ||
4991 (kind() == MathUnaryInstr::kDoubleSquare)); 4791 (kind() == MathUnaryInstr::kDoubleSquare));
4992 const intptr_t kNumInputs = 1; 4792 const intptr_t kNumInputs = 1;
4993 const intptr_t kNumTemps = 0; 4793 const intptr_t kNumTemps = 0;
4994 LocationSummary* summary = new (zone) 4794 LocationSummary* summary = new (zone)
4995 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4795 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4996 summary->set_in(0, Location::RequiresFpuRegister()); 4796 summary->set_in(0, Location::RequiresFpuRegister());
4997 if (kind() == MathUnaryInstr::kDoubleSquare) { 4797 if (kind() == MathUnaryInstr::kDoubleSquare) {
4998 summary->set_out(0, Location::SameAsFirstInput()); 4798 summary->set_out(0, Location::SameAsFirstInput());
4999 } else { 4799 } else {
5000 summary->set_out(0, Location::RequiresFpuRegister()); 4800 summary->set_out(0, Location::RequiresFpuRegister());
5001 } 4801 }
5002 return summary; 4802 return summary;
5003 } 4803 }
5004 4804
5005
5006 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4805 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5007 if (kind() == MathUnaryInstr::kSqrt) { 4806 if (kind() == MathUnaryInstr::kSqrt) {
5008 __ sqrtsd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg()); 4807 __ sqrtsd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
5009 } else if (kind() == MathUnaryInstr::kDoubleSquare) { 4808 } else if (kind() == MathUnaryInstr::kDoubleSquare) {
5010 XmmRegister value_reg = locs()->in(0).fpu_reg(); 4809 XmmRegister value_reg = locs()->in(0).fpu_reg();
5011 __ mulsd(value_reg, value_reg); 4810 __ mulsd(value_reg, value_reg);
5012 ASSERT(value_reg == locs()->out(0).fpu_reg()); 4811 ASSERT(value_reg == locs()->out(0).fpu_reg());
5013 } else { 4812 } else {
5014 UNREACHABLE(); 4813 UNREACHABLE();
5015 } 4814 }
5016 } 4815 }
5017 4816
5018
5019 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( 4817 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary(
5020 Zone* zone, 4818 Zone* zone,
5021 bool opt) const { 4819 bool opt) const {
5022 const intptr_t kNumTemps = 0; 4820 const intptr_t kNumTemps = 0;
5023 LocationSummary* summary = new (zone) 4821 LocationSummary* summary = new (zone)
5024 LocationSummary(zone, InputCount(), kNumTemps, LocationSummary::kCall); 4822 LocationSummary(zone, InputCount(), kNumTemps, LocationSummary::kCall);
5025 summary->set_in(0, Location::RegisterLocation(EAX)); 4823 summary->set_in(0, Location::RegisterLocation(EAX));
5026 summary->set_in(1, Location::RegisterLocation(ECX)); 4824 summary->set_in(1, Location::RegisterLocation(ECX));
5027 summary->set_in(2, Location::RegisterLocation(EDX)); 4825 summary->set_in(2, Location::RegisterLocation(EDX));
5028 summary->set_in(3, Location::RegisterLocation(EBX)); 4826 summary->set_in(3, Location::RegisterLocation(EBX));
5029 summary->set_out(0, Location::RegisterLocation(EAX)); 4827 summary->set_out(0, Location::RegisterLocation(EAX));
5030 return summary; 4828 return summary;
5031 } 4829 }
5032 4830
5033
5034 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( 4831 void CaseInsensitiveCompareUC16Instr::EmitNativeCode(
5035 FlowGraphCompiler* compiler) { 4832 FlowGraphCompiler* compiler) {
5036 // Save ESP. EDI is chosen because it is callee saved so we do not need to 4833 // Save ESP. EDI is chosen because it is callee saved so we do not need to
5037 // back it up before calling into the runtime. 4834 // back it up before calling into the runtime.
5038 static const Register kSavedSPReg = EDI; 4835 static const Register kSavedSPReg = EDI;
5039 __ movl(kSavedSPReg, ESP); 4836 __ movl(kSavedSPReg, ESP);
5040 __ ReserveAlignedFrameSpace(kWordSize * TargetFunction().argument_count()); 4837 __ ReserveAlignedFrameSpace(kWordSize * TargetFunction().argument_count());
5041 4838
5042 __ movl(Address(ESP, +0 * kWordSize), locs()->in(0).reg()); 4839 __ movl(Address(ESP, +0 * kWordSize), locs()->in(0).reg());
5043 __ movl(Address(ESP, +1 * kWordSize), locs()->in(1).reg()); 4840 __ movl(Address(ESP, +1 * kWordSize), locs()->in(1).reg());
5044 __ movl(Address(ESP, +2 * kWordSize), locs()->in(2).reg()); 4841 __ movl(Address(ESP, +2 * kWordSize), locs()->in(2).reg());
5045 __ movl(Address(ESP, +3 * kWordSize), locs()->in(3).reg()); 4842 __ movl(Address(ESP, +3 * kWordSize), locs()->in(3).reg());
5046 4843
5047 // Call the function. 4844 // Call the function.
5048 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); 4845 __ CallRuntime(TargetFunction(), TargetFunction().argument_count());
5049 4846
5050 // Restore ESP. 4847 // Restore ESP.
5051 __ movl(ESP, kSavedSPReg); 4848 __ movl(ESP, kSavedSPReg);
5052 } 4849 }
5053 4850
5054
5055 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Zone* zone, 4851 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Zone* zone,
5056 bool opt) const { 4852 bool opt) const {
5057 if (result_cid() == kDoubleCid) { 4853 if (result_cid() == kDoubleCid) {
5058 const intptr_t kNumInputs = 2; 4854 const intptr_t kNumInputs = 2;
5059 const intptr_t kNumTemps = 1; 4855 const intptr_t kNumTemps = 1;
5060 LocationSummary* summary = new (zone) 4856 LocationSummary* summary = new (zone)
5061 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4857 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5062 summary->set_in(0, Location::RequiresFpuRegister()); 4858 summary->set_in(0, Location::RequiresFpuRegister());
5063 summary->set_in(1, Location::RequiresFpuRegister()); 4859 summary->set_in(1, Location::RequiresFpuRegister());
5064 // Reuse the left register so that code can be made shorter. 4860 // Reuse the left register so that code can be made shorter.
5065 summary->set_out(0, Location::SameAsFirstInput()); 4861 summary->set_out(0, Location::SameAsFirstInput());
5066 summary->set_temp(0, Location::RequiresRegister()); 4862 summary->set_temp(0, Location::RequiresRegister());
5067 return summary; 4863 return summary;
5068 } 4864 }
5069 4865
5070 ASSERT(result_cid() == kSmiCid); 4866 ASSERT(result_cid() == kSmiCid);
5071 const intptr_t kNumInputs = 2; 4867 const intptr_t kNumInputs = 2;
5072 const intptr_t kNumTemps = 0; 4868 const intptr_t kNumTemps = 0;
5073 LocationSummary* summary = new (zone) 4869 LocationSummary* summary = new (zone)
5074 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4870 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5075 summary->set_in(0, Location::RequiresRegister()); 4871 summary->set_in(0, Location::RequiresRegister());
5076 summary->set_in(1, Location::RequiresRegister()); 4872 summary->set_in(1, Location::RequiresRegister());
5077 // Reuse the left register so that code can be made shorter. 4873 // Reuse the left register so that code can be made shorter.
5078 summary->set_out(0, Location::SameAsFirstInput()); 4874 summary->set_out(0, Location::SameAsFirstInput());
5079 return summary; 4875 return summary;
5080 } 4876 }
5081 4877
5082
5083 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4878 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5084 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 4879 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
5085 (op_kind() == MethodRecognizer::kMathMax)); 4880 (op_kind() == MethodRecognizer::kMathMax));
5086 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); 4881 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
5087 if (result_cid() == kDoubleCid) { 4882 if (result_cid() == kDoubleCid) {
5088 Label done, returns_nan, are_equal; 4883 Label done, returns_nan, are_equal;
5089 XmmRegister left = locs()->in(0).fpu_reg(); 4884 XmmRegister left = locs()->in(0).fpu_reg();
5090 XmmRegister right = locs()->in(1).fpu_reg(); 4885 XmmRegister right = locs()->in(1).fpu_reg();
5091 XmmRegister result = locs()->out(0).fpu_reg(); 4886 XmmRegister result = locs()->out(0).fpu_reg();
5092 Register temp = locs()->temp(0).reg(); 4887 Register temp = locs()->temp(0).reg();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
5133 Register result = locs()->out(0).reg(); 4928 Register result = locs()->out(0).reg();
5134 __ cmpl(left, right); 4929 __ cmpl(left, right);
5135 ASSERT(result == left); 4930 ASSERT(result == left);
5136 if (is_min) { 4931 if (is_min) {
5137 __ cmovgel(result, right); 4932 __ cmovgel(result, right);
5138 } else { 4933 } else {
5139 __ cmovlessl(result, right); 4934 __ cmovlessl(result, right);
5140 } 4935 }
5141 } 4936 }
5142 4937
5143
5144 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Zone* zone, 4938 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Zone* zone,
5145 bool opt) const { 4939 bool opt) const {
5146 const intptr_t kNumInputs = 1; 4940 const intptr_t kNumInputs = 1;
5147 return LocationSummary::Make(zone, kNumInputs, Location::SameAsFirstInput(), 4941 return LocationSummary::Make(zone, kNumInputs, Location::SameAsFirstInput(),
5148 LocationSummary::kNoCall); 4942 LocationSummary::kNoCall);
5149 } 4943 }
5150 4944
5151
5152 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4945 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5153 Register value = locs()->in(0).reg(); 4946 Register value = locs()->in(0).reg();
5154 ASSERT(value == locs()->out(0).reg()); 4947 ASSERT(value == locs()->out(0).reg());
5155 switch (op_kind()) { 4948 switch (op_kind()) {
5156 case Token::kNEGATE: { 4949 case Token::kNEGATE: {
5157 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); 4950 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
5158 __ negl(value); 4951 __ negl(value);
5159 __ j(OVERFLOW, deopt); 4952 __ j(OVERFLOW, deopt);
5160 break; 4953 break;
5161 } 4954 }
5162 case Token::kBIT_NOT: 4955 case Token::kBIT_NOT:
5163 __ notl(value); 4956 __ notl(value);
5164 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 4957 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
5165 break; 4958 break;
5166 default: 4959 default:
5167 UNREACHABLE(); 4960 UNREACHABLE();
5168 } 4961 }
5169 } 4962 }
5170 4963
5171
5172 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone, 4964 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
5173 bool opt) const { 4965 bool opt) const {
5174 const intptr_t kNumInputs = 1; 4966 const intptr_t kNumInputs = 1;
5175 const intptr_t kNumTemps = 0; 4967 const intptr_t kNumTemps = 0;
5176 LocationSummary* summary = new (zone) 4968 LocationSummary* summary = new (zone)
5177 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4969 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5178 summary->set_in(0, Location::RequiresFpuRegister()); 4970 summary->set_in(0, Location::RequiresFpuRegister());
5179 summary->set_out(0, Location::SameAsFirstInput()); 4971 summary->set_out(0, Location::SameAsFirstInput());
5180 return summary; 4972 return summary;
5181 } 4973 }
5182 4974
5183
5184 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4975 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5185 XmmRegister value = locs()->in(0).fpu_reg(); 4976 XmmRegister value = locs()->in(0).fpu_reg();
5186 ASSERT(locs()->out(0).fpu_reg() == value); 4977 ASSERT(locs()->out(0).fpu_reg() == value);
5187 __ DoubleNegate(value); 4978 __ DoubleNegate(value);
5188 } 4979 }
5189 4980
5190
5191 LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone, 4981 LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Zone* zone,
5192 bool opt) const { 4982 bool opt) const {
5193 const intptr_t kNumInputs = 1; 4983 const intptr_t kNumInputs = 1;
5194 const intptr_t kNumTemps = 0; 4984 const intptr_t kNumTemps = 0;
5195 LocationSummary* result = new (zone) 4985 LocationSummary* result = new (zone)
5196 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4986 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5197 result->set_in(0, Location::RequiresRegister()); 4987 result->set_in(0, Location::RequiresRegister());
5198 result->set_out(0, Location::RequiresFpuRegister()); 4988 result->set_out(0, Location::RequiresFpuRegister());
5199 return result; 4989 return result;
5200 } 4990 }
5201 4991
5202
5203 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4992 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5204 Register value = locs()->in(0).reg(); 4993 Register value = locs()->in(0).reg();
5205 FpuRegister result = locs()->out(0).fpu_reg(); 4994 FpuRegister result = locs()->out(0).fpu_reg();
5206 __ cvtsi2sd(result, value); 4995 __ cvtsi2sd(result, value);
5207 } 4996 }
5208 4997
5209
5210 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Zone* zone, 4998 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Zone* zone,
5211 bool opt) const { 4999 bool opt) const {
5212 const intptr_t kNumInputs = 1; 5000 const intptr_t kNumInputs = 1;
5213 const intptr_t kNumTemps = 0; 5001 const intptr_t kNumTemps = 0;
5214 LocationSummary* result = new (zone) 5002 LocationSummary* result = new (zone)
5215 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5003 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5216 result->set_in(0, Location::WritableRegister()); 5004 result->set_in(0, Location::WritableRegister());
5217 result->set_out(0, Location::RequiresFpuRegister()); 5005 result->set_out(0, Location::RequiresFpuRegister());
5218 return result; 5006 return result;
5219 } 5007 }
5220 5008
5221
5222 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5009 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5223 Register value = locs()->in(0).reg(); 5010 Register value = locs()->in(0).reg();
5224 FpuRegister result = locs()->out(0).fpu_reg(); 5011 FpuRegister result = locs()->out(0).fpu_reg();
5225 __ SmiUntag(value); 5012 __ SmiUntag(value);
5226 __ cvtsi2sd(result, value); 5013 __ cvtsi2sd(result, value);
5227 } 5014 }
5228 5015
5229
5230 LocationSummary* MintToDoubleInstr::MakeLocationSummary(Zone* zone, 5016 LocationSummary* MintToDoubleInstr::MakeLocationSummary(Zone* zone,
5231 bool opt) const { 5017 bool opt) const {
5232 const intptr_t kNumInputs = 1; 5018 const intptr_t kNumInputs = 1;
5233 const intptr_t kNumTemps = 0; 5019 const intptr_t kNumTemps = 0;
5234 LocationSummary* result = new (zone) 5020 LocationSummary* result = new (zone)
5235 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5021 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5236 result->set_in(0, Location::Pair(Location::RequiresRegister(), 5022 result->set_in(0, Location::Pair(Location::RequiresRegister(),
5237 Location::RequiresRegister())); 5023 Location::RequiresRegister()));
5238 result->set_out(0, Location::RequiresFpuRegister()); 5024 result->set_out(0, Location::RequiresFpuRegister());
5239 return result; 5025 return result;
5240 } 5026 }
5241 5027
5242
5243 void MintToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5028 void MintToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5244 PairLocation* pair = locs()->in(0).AsPairLocation(); 5029 PairLocation* pair = locs()->in(0).AsPairLocation();
5245 Register in_lo = pair->At(0).reg(); 5030 Register in_lo = pair->At(0).reg();
5246 Register in_hi = pair->At(1).reg(); 5031 Register in_hi = pair->At(1).reg();
5247 5032
5248 FpuRegister result = locs()->out(0).fpu_reg(); 5033 FpuRegister result = locs()->out(0).fpu_reg();
5249 5034
5250 // Push hi. 5035 // Push hi.
5251 __ pushl(in_hi); 5036 __ pushl(in_hi);
5252 // Push lo. 5037 // Push lo.
5253 __ pushl(in_lo); 5038 __ pushl(in_lo);
5254 // Perform conversion from Mint to double. 5039 // Perform conversion from Mint to double.
5255 __ fildl(Address(ESP, 0)); 5040 __ fildl(Address(ESP, 0));
5256 // Pop FPU stack onto regular stack. 5041 // Pop FPU stack onto regular stack.
5257 __ fstpl(Address(ESP, 0)); 5042 __ fstpl(Address(ESP, 0));
5258 // Copy into result. 5043 // Copy into result.
5259 __ movsd(result, Address(ESP, 0)); 5044 __ movsd(result, Address(ESP, 0));
5260 // Pop args. 5045 // Pop args.
5261 __ addl(ESP, Immediate(2 * kWordSize)); 5046 __ addl(ESP, Immediate(2 * kWordSize));
5262 } 5047 }
5263 5048
5264
5265 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Zone* zone, 5049 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(Zone* zone,
5266 bool opt) const { 5050 bool opt) const {
5267 const intptr_t kNumInputs = 1; 5051 const intptr_t kNumInputs = 1;
5268 const intptr_t kNumTemps = 0; 5052 const intptr_t kNumTemps = 0;
5269 LocationSummary* result = new (zone) 5053 LocationSummary* result = new (zone)
5270 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 5054 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
5271 result->set_in(0, Location::RegisterLocation(ECX)); 5055 result->set_in(0, Location::RegisterLocation(ECX));
5272 result->set_out(0, Location::RegisterLocation(EAX)); 5056 result->set_out(0, Location::RegisterLocation(EAX));
5273 return result; 5057 return result;
5274 } 5058 }
5275 5059
5276
5277 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5060 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5278 Register result = locs()->out(0).reg(); 5061 Register result = locs()->out(0).reg();
5279 Register value_obj = locs()->in(0).reg(); 5062 Register value_obj = locs()->in(0).reg();
5280 XmmRegister value_double = XMM0; 5063 XmmRegister value_double = XMM0;
5281 ASSERT(result == EAX); 5064 ASSERT(result == EAX);
5282 ASSERT(result != value_obj); 5065 ASSERT(result != value_obj);
5283 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset())); 5066 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset()));
5284 __ cvttsd2si(result, value_double); 5067 __ cvttsd2si(result, value_double);
5285 // Overflow is signalled with minint. 5068 // Overflow is signalled with minint.
5286 Label do_call, done; 5069 Label do_call, done;
(...skipping 10 matching lines...) Expand all
5297 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 5080 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
5298 const int kTypeArgsLen = 0; 5081 const int kTypeArgsLen = 0;
5299 const int kNumberOfArguments = 1; 5082 const int kNumberOfArguments = 1;
5300 const Array& kNoArgumentNames = Object::null_array(); 5083 const Array& kNoArgumentNames = Object::null_array();
5301 ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames); 5084 ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
5302 compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target, 5085 compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target,
5303 args_info, locs(), ICData::Handle()); 5086 args_info, locs(), ICData::Handle());
5304 __ Bind(&done); 5087 __ Bind(&done);
5305 } 5088 }
5306 5089
5307
5308 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(Zone* zone, 5090 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(Zone* zone,
5309 bool opt) const { 5091 bool opt) const {
5310 const intptr_t kNumInputs = 1; 5092 const intptr_t kNumInputs = 1;
5311 const intptr_t kNumTemps = 0; 5093 const intptr_t kNumTemps = 0;
5312 LocationSummary* result = new (zone) 5094 LocationSummary* result = new (zone)
5313 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5095 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5314 result->set_in(0, Location::RequiresFpuRegister()); 5096 result->set_in(0, Location::RequiresFpuRegister());
5315 result->set_out(0, Location::RequiresRegister()); 5097 result->set_out(0, Location::RequiresRegister());
5316 return result; 5098 return result;
5317 } 5099 }
5318 5100
5319
5320 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5101 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5321 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi); 5102 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi);
5322 Register result = locs()->out(0).reg(); 5103 Register result = locs()->out(0).reg();
5323 XmmRegister value = locs()->in(0).fpu_reg(); 5104 XmmRegister value = locs()->in(0).fpu_reg();
5324 __ cvttsd2si(result, value); 5105 __ cvttsd2si(result, value);
5325 // Check for overflow and that it fits into Smi. 5106 // Check for overflow and that it fits into Smi.
5326 __ cmpl(result, Immediate(0xC0000000)); 5107 __ cmpl(result, Immediate(0xC0000000));
5327 __ j(NEGATIVE, deopt); 5108 __ j(NEGATIVE, deopt);
5328 __ SmiTag(result); 5109 __ SmiTag(result);
5329 } 5110 }
5330 5111
5331
5332 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone, 5112 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
5333 bool opt) const { 5113 bool opt) const {
5334 const intptr_t kNumInputs = 1; 5114 const intptr_t kNumInputs = 1;
5335 const intptr_t kNumTemps = 0; 5115 const intptr_t kNumTemps = 0;
5336 LocationSummary* result = new (zone) 5116 LocationSummary* result = new (zone)
5337 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5117 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5338 result->set_in(0, Location::RequiresFpuRegister()); 5118 result->set_in(0, Location::RequiresFpuRegister());
5339 result->set_out(0, Location::RequiresFpuRegister()); 5119 result->set_out(0, Location::RequiresFpuRegister());
5340 return result; 5120 return result;
5341 } 5121 }
5342 5122
5343
5344 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5123 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5345 XmmRegister value = locs()->in(0).fpu_reg(); 5124 XmmRegister value = locs()->in(0).fpu_reg();
5346 XmmRegister result = locs()->out(0).fpu_reg(); 5125 XmmRegister result = locs()->out(0).fpu_reg();
5347 switch (recognized_kind()) { 5126 switch (recognized_kind()) {
5348 case MethodRecognizer::kDoubleTruncate: 5127 case MethodRecognizer::kDoubleTruncate:
5349 __ roundsd(result, value, Assembler::kRoundToZero); 5128 __ roundsd(result, value, Assembler::kRoundToZero);
5350 break; 5129 break;
5351 case MethodRecognizer::kDoubleFloor: 5130 case MethodRecognizer::kDoubleFloor:
5352 __ roundsd(result, value, Assembler::kRoundDown); 5131 __ roundsd(result, value, Assembler::kRoundDown);
5353 break; 5132 break;
5354 case MethodRecognizer::kDoubleCeil: 5133 case MethodRecognizer::kDoubleCeil:
5355 __ roundsd(result, value, Assembler::kRoundUp); 5134 __ roundsd(result, value, Assembler::kRoundUp);
5356 break; 5135 break;
5357 default: 5136 default:
5358 UNREACHABLE(); 5137 UNREACHABLE();
5359 } 5138 }
5360 } 5139 }
5361 5140
5362
5363 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone, 5141 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(Zone* zone,
5364 bool opt) const { 5142 bool opt) const {
5365 const intptr_t kNumInputs = 1; 5143 const intptr_t kNumInputs = 1;
5366 const intptr_t kNumTemps = 0; 5144 const intptr_t kNumTemps = 0;
5367 LocationSummary* result = new (zone) 5145 LocationSummary* result = new (zone)
5368 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5146 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5369 result->set_in(0, Location::RequiresFpuRegister()); 5147 result->set_in(0, Location::RequiresFpuRegister());
5370 result->set_out(0, Location::SameAsFirstInput()); 5148 result->set_out(0, Location::SameAsFirstInput());
5371 return result; 5149 return result;
5372 } 5150 }
5373 5151
5374
5375 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5152 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5376 __ cvtsd2ss(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg()); 5153 __ cvtsd2ss(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
5377 } 5154 }
5378 5155
5379
5380 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(Zone* zone, 5156 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(Zone* zone,
5381 bool opt) const { 5157 bool opt) const {
5382 const intptr_t kNumInputs = 1; 5158 const intptr_t kNumInputs = 1;
5383 const intptr_t kNumTemps = 0; 5159 const intptr_t kNumTemps = 0;
5384 LocationSummary* result = new (zone) 5160 LocationSummary* result = new (zone)
5385 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5161 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5386 result->set_in(0, Location::RequiresFpuRegister()); 5162 result->set_in(0, Location::RequiresFpuRegister());
5387 result->set_out(0, Location::SameAsFirstInput()); 5163 result->set_out(0, Location::SameAsFirstInput());
5388 return result; 5164 return result;
5389 } 5165 }
5390 5166
5391
5392 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5167 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5393 __ cvtss2sd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg()); 5168 __ cvtss2sd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
5394 } 5169 }
5395 5170
5396
5397 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone, 5171 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
5398 bool opt) const { 5172 bool opt) const {
5399 ASSERT((InputCount() == 1) || (InputCount() == 2)); 5173 ASSERT((InputCount() == 1) || (InputCount() == 2));
5400 const intptr_t kNumTemps = 5174 const intptr_t kNumTemps =
5401 (recognized_kind() == MethodRecognizer::kMathDoublePow) ? 3 : 1; 5175 (recognized_kind() == MethodRecognizer::kMathDoublePow) ? 3 : 1;
5402 LocationSummary* result = new (zone) 5176 LocationSummary* result = new (zone)
5403 LocationSummary(zone, InputCount(), kNumTemps, LocationSummary::kCall); 5177 LocationSummary(zone, InputCount(), kNumTemps, LocationSummary::kCall);
5404 // EDI is chosen because it is callee saved so we do not need to back it 5178 // EDI is chosen because it is callee saved so we do not need to back it
5405 // up before calling into the runtime. 5179 // up before calling into the runtime.
5406 result->set_temp(0, Location::RegisterLocation(EDI)); 5180 result->set_temp(0, Location::RegisterLocation(EDI));
5407 result->set_in(0, Location::FpuRegisterLocation(XMM1)); 5181 result->set_in(0, Location::FpuRegisterLocation(XMM1));
5408 if (InputCount() == 2) { 5182 if (InputCount() == 2) {
5409 result->set_in(1, Location::FpuRegisterLocation(XMM2)); 5183 result->set_in(1, Location::FpuRegisterLocation(XMM2));
5410 } 5184 }
5411 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 5185 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
5412 // Temp index 1. 5186 // Temp index 1.
5413 result->set_temp(1, Location::RegisterLocation(EAX)); 5187 result->set_temp(1, Location::RegisterLocation(EAX));
5414 // Temp index 2. 5188 // Temp index 2.
5415 result->set_temp(2, Location::FpuRegisterLocation(XMM4)); 5189 result->set_temp(2, Location::FpuRegisterLocation(XMM4));
5416 } 5190 }
5417 result->set_out(0, Location::FpuRegisterLocation(XMM3)); 5191 result->set_out(0, Location::FpuRegisterLocation(XMM3));
5418 return result; 5192 return result;
5419 } 5193 }
5420 5194
5421
5422 // Pseudo code: 5195 // Pseudo code:
5423 // if (exponent == 0.0) return 1.0; 5196 // if (exponent == 0.0) return 1.0;
5424 // // Speed up simple cases. 5197 // // Speed up simple cases.
5425 // if (exponent == 1.0) return base; 5198 // if (exponent == 1.0) return base;
5426 // if (exponent == 2.0) return base * base; 5199 // if (exponent == 2.0) return base * base;
5427 // if (exponent == 3.0) return base * base * base; 5200 // if (exponent == 3.0) return base * base * base;
5428 // if (base == 1.0) return 1.0; 5201 // if (base == 1.0) return 1.0;
5429 // if (base.isNaN || exponent.isNaN) { 5202 // if (base.isNaN || exponent.isNaN) {
5430 // return double.NAN; 5203 // return double.NAN;
5431 // } 5204 // }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
5544 __ movsd(Address(ESP, kDoubleSize * i), locs->in(i).fpu_reg()); 5317 __ movsd(Address(ESP, kDoubleSize * i), locs->in(i).fpu_reg());
5545 } 5318 }
5546 __ CallRuntime(instr->TargetFunction(), kInputCount); 5319 __ CallRuntime(instr->TargetFunction(), kInputCount);
5547 __ fstpl(Address(ESP, 0)); 5320 __ fstpl(Address(ESP, 0));
5548 __ movsd(locs->out(0).fpu_reg(), Address(ESP, 0)); 5321 __ movsd(locs->out(0).fpu_reg(), Address(ESP, 0));
5549 // Restore ESP. 5322 // Restore ESP.
5550 __ movl(ESP, locs->temp(InvokeMathCFunctionInstr::kSavedSpTempIndex).reg()); 5323 __ movl(ESP, locs->temp(InvokeMathCFunctionInstr::kSavedSpTempIndex).reg());
5551 __ Bind(&skip_call); 5324 __ Bind(&skip_call);
5552 } 5325 }
5553 5326
5554
5555 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5327 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5556 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 5328 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
5557 InvokeDoublePow(compiler, this); 5329 InvokeDoublePow(compiler, this);
5558 return; 5330 return;
5559 } 5331 }
5560 // Save ESP. 5332 // Save ESP.
5561 __ movl(locs()->temp(kSavedSpTempIndex).reg(), ESP); 5333 __ movl(locs()->temp(kSavedSpTempIndex).reg(), ESP);
5562 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 5334 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
5563 for (intptr_t i = 0; i < InputCount(); i++) { 5335 for (intptr_t i = 0; i < InputCount(); i++) {
5564 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg()); 5336 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg());
5565 } 5337 }
5566 5338
5567 __ CallRuntime(TargetFunction(), InputCount()); 5339 __ CallRuntime(TargetFunction(), InputCount());
5568 __ fstpl(Address(ESP, 0)); 5340 __ fstpl(Address(ESP, 0));
5569 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); 5341 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
5570 // Restore ESP. 5342 // Restore ESP.
5571 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg()); 5343 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg());
5572 } 5344 }
5573 5345
5574
5575 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(Zone* zone, 5346 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(Zone* zone,
5576 bool opt) const { 5347 bool opt) const {
5577 // Only use this instruction in optimized code. 5348 // Only use this instruction in optimized code.
5578 ASSERT(opt); 5349 ASSERT(opt);
5579 const intptr_t kNumInputs = 1; 5350 const intptr_t kNumInputs = 1;
5580 LocationSummary* summary = 5351 LocationSummary* summary =
5581 new (zone) LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall); 5352 new (zone) LocationSummary(zone, kNumInputs, 0, LocationSummary::kNoCall);
5582 if (representation() == kUnboxedDouble) { 5353 if (representation() == kUnboxedDouble) {
5583 if (index() == 0) { 5354 if (index() == 0) {
5584 summary->set_in( 5355 summary->set_in(
(...skipping 12 matching lines...) Expand all
5597 } else { 5368 } else {
5598 ASSERT(index() == 1); 5369 ASSERT(index() == 1);
5599 summary->set_in( 5370 summary->set_in(
5600 0, Location::Pair(Location::Any(), Location::RequiresRegister())); 5371 0, Location::Pair(Location::Any(), Location::RequiresRegister()));
5601 } 5372 }
5602 summary->set_out(0, Location::RequiresRegister()); 5373 summary->set_out(0, Location::RequiresRegister());
5603 } 5374 }
5604 return summary; 5375 return summary;
5605 } 5376 }
5606 5377
5607
5608 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5378 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5609 ASSERT(locs()->in(0).IsPairLocation()); 5379 ASSERT(locs()->in(0).IsPairLocation());
5610 PairLocation* pair = locs()->in(0).AsPairLocation(); 5380 PairLocation* pair = locs()->in(0).AsPairLocation();
5611 Location in_loc = pair->At(index()); 5381 Location in_loc = pair->At(index());
5612 if (representation() == kUnboxedDouble) { 5382 if (representation() == kUnboxedDouble) {
5613 XmmRegister out = locs()->out(0).fpu_reg(); 5383 XmmRegister out = locs()->out(0).fpu_reg();
5614 XmmRegister in = in_loc.fpu_reg(); 5384 XmmRegister in = in_loc.fpu_reg();
5615 __ movaps(out, in); 5385 __ movaps(out, in);
5616 } else { 5386 } else {
5617 ASSERT(representation() == kTagged); 5387 ASSERT(representation() == kTagged);
5618 Register out = locs()->out(0).reg(); 5388 Register out = locs()->out(0).reg();
5619 Register in = in_loc.reg(); 5389 Register in = in_loc.reg();
5620 __ movl(out, in); 5390 __ movl(out, in);
5621 } 5391 }
5622 } 5392 }
5623 5393
5624
5625 LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone, 5394 LocationSummary* TruncDivModInstr::MakeLocationSummary(Zone* zone,
5626 bool opt) const { 5395 bool opt) const {
5627 const intptr_t kNumInputs = 2; 5396 const intptr_t kNumInputs = 2;
5628 const intptr_t kNumTemps = 0; 5397 const intptr_t kNumTemps = 0;
5629 LocationSummary* summary = new (zone) 5398 LocationSummary* summary = new (zone)
5630 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5399 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5631 // Both inputs must be writable because they will be untagged. 5400 // Both inputs must be writable because they will be untagged.
5632 summary->set_in(0, Location::RegisterLocation(EAX)); 5401 summary->set_in(0, Location::RegisterLocation(EAX));
5633 summary->set_in(1, Location::WritableRegister()); 5402 summary->set_in(1, Location::WritableRegister());
5634 // Output is a pair of registers. 5403 // Output is a pair of registers.
5635 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), 5404 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
5636 Location::RegisterLocation(EDX))); 5405 Location::RegisterLocation(EDX)));
5637 return summary; 5406 return summary;
5638 } 5407 }
5639 5408
5640
5641 void TruncDivModInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5409 void TruncDivModInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5642 ASSERT(CanDeoptimize()); 5410 ASSERT(CanDeoptimize());
5643 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); 5411 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
5644 Register left = locs()->in(0).reg(); 5412 Register left = locs()->in(0).reg();
5645 Register right = locs()->in(1).reg(); 5413 Register right = locs()->in(1).reg();
5646 ASSERT(locs()->out(0).IsPairLocation()); 5414 ASSERT(locs()->out(0).IsPairLocation());
5647 PairLocation* pair = locs()->out(0).AsPairLocation(); 5415 PairLocation* pair = locs()->out(0).AsPairLocation();
5648 Register result1 = pair->At(0).reg(); 5416 Register result1 = pair->At(0).reg();
5649 Register result2 = pair->At(1).reg(); 5417 Register result2 = pair->At(1).reg();
5650 if (RangeUtils::CanBeZero(divisor_range())) { 5418 if (RangeUtils::CanBeZero(divisor_range())) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
5694 } else { 5462 } else {
5695 // Right is negative. 5463 // Right is negative.
5696 __ subl(EDX, right); 5464 __ subl(EDX, right);
5697 } 5465 }
5698 __ Bind(&done); 5466 __ Bind(&done);
5699 5467
5700 __ SmiTag(EAX); 5468 __ SmiTag(EAX);
5701 __ SmiTag(EDX); 5469 __ SmiTag(EDX);
5702 } 5470 }
5703 5471
5704
5705 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( 5472 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
5706 Zone* zone, 5473 Zone* zone,
5707 bool opt) const { 5474 bool opt) const {
5708 return MakeCallSummary(zone); 5475 return MakeCallSummary(zone);
5709 } 5476 }
5710 5477
5711
5712 LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const { 5478 LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
5713 comparison()->InitializeLocationSummary(zone, opt); 5479 comparison()->InitializeLocationSummary(zone, opt);
5714 // Branches don't produce a result. 5480 // Branches don't produce a result.
5715 comparison()->locs()->set_out(0, Location::NoLocation()); 5481 comparison()->locs()->set_out(0, Location::NoLocation());
5716 return comparison()->locs(); 5482 return comparison()->locs();
5717 } 5483 }
5718 5484
5719
5720 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5485 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5721 comparison()->EmitBranchCode(compiler, this); 5486 comparison()->EmitBranchCode(compiler, this);
5722 } 5487 }
5723 5488
5724
5725 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 5489 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
5726 bool opt) const { 5490 bool opt) const {
5727 const intptr_t kNumInputs = 1; 5491 const intptr_t kNumInputs = 1;
5728 const bool need_mask_temp = IsBitTest(); 5492 const bool need_mask_temp = IsBitTest();
5729 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 5493 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
5730 LocationSummary* summary = new (zone) 5494 LocationSummary* summary = new (zone)
5731 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5495 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5732 summary->set_in(0, Location::RequiresRegister()); 5496 summary->set_in(0, Location::RequiresRegister());
5733 if (!IsNullCheck()) { 5497 if (!IsNullCheck()) {
5734 summary->set_temp(0, Location::RequiresRegister()); 5498 summary->set_temp(0, Location::RequiresRegister());
5735 if (need_mask_temp) { 5499 if (need_mask_temp) {
5736 summary->set_temp(1, Location::RequiresRegister()); 5500 summary->set_temp(1, Location::RequiresRegister());
5737 } 5501 }
5738 } 5502 }
5739 return summary; 5503 return summary;
5740 } 5504 }
5741 5505
5742
5743 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) { 5506 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) {
5744 const Immediate& raw_null = 5507 const Immediate& raw_null =
5745 Immediate(reinterpret_cast<intptr_t>(Object::null())); 5508 Immediate(reinterpret_cast<intptr_t>(Object::null()));
5746 __ cmpl(locs()->in(0).reg(), raw_null); 5509 __ cmpl(locs()->in(0).reg(), raw_null);
5747 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull()); 5510 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
5748 Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL; 5511 Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL;
5749 __ j(cond, deopt); 5512 __ j(cond, deopt);
5750 } 5513 }
5751 5514
5752
5753 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, 5515 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler,
5754 intptr_t min, 5516 intptr_t min,
5755 intptr_t max, 5517 intptr_t max,
5756 intptr_t mask, 5518 intptr_t mask,
5757 Label* deopt) { 5519 Label* deopt) {
5758 Register biased_cid = locs()->temp(0).reg(); 5520 Register biased_cid = locs()->temp(0).reg();
5759 __ subl(biased_cid, Immediate(min)); 5521 __ subl(biased_cid, Immediate(min));
5760 __ cmpl(biased_cid, Immediate(max - min)); 5522 __ cmpl(biased_cid, Immediate(max - min));
5761 __ j(ABOVE, deopt); 5523 __ j(ABOVE, deopt);
5762 5524
5763 Register mask_reg = locs()->temp(1).reg(); 5525 Register mask_reg = locs()->temp(1).reg();
5764 __ movl(mask_reg, Immediate(mask)); 5526 __ movl(mask_reg, Immediate(mask));
5765 __ bt(mask_reg, biased_cid); 5527 __ bt(mask_reg, biased_cid);
5766 __ j(NOT_CARRY, deopt); 5528 __ j(NOT_CARRY, deopt);
5767 } 5529 }
5768 5530
5769
5770 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, 5531 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler,
5771 int bias, 5532 int bias,
5772 intptr_t cid_start, 5533 intptr_t cid_start,
5773 intptr_t cid_end, 5534 intptr_t cid_end,
5774 bool is_last, 5535 bool is_last,
5775 Label* is_ok, 5536 Label* is_ok,
5776 Label* deopt, 5537 Label* deopt,
5777 bool use_near_jump) { 5538 bool use_near_jump) {
5778 Register biased_cid = locs()->temp(0).reg(); 5539 Register biased_cid = locs()->temp(0).reg();
5779 Condition no_match, match; 5540 Condition no_match, match;
(...skipping 16 matching lines...) Expand all
5796 } else { 5557 } else {
5797 if (use_near_jump) { 5558 if (use_near_jump) {
5798 __ j(match, is_ok, Assembler::kNearJump); 5559 __ j(match, is_ok, Assembler::kNearJump);
5799 } else { 5560 } else {
5800 __ j(match, is_ok); 5561 __ j(match, is_ok);
5801 } 5562 }
5802 } 5563 }
5803 return bias; 5564 return bias;
5804 } 5565 }
5805 5566
5806
5807 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, 5567 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone,
5808 bool opt) const { 5568 bool opt) const {
5809 const intptr_t kNumInputs = 1; 5569 const intptr_t kNumInputs = 1;
5810 const intptr_t kNumTemps = 0; 5570 const intptr_t kNumTemps = 0;
5811 LocationSummary* summary = new (zone) 5571 LocationSummary* summary = new (zone)
5812 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5572 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5813 summary->set_in(0, Location::RequiresRegister()); 5573 summary->set_in(0, Location::RequiresRegister());
5814 return summary; 5574 return summary;
5815 } 5575 }
5816 5576
5817
5818 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5577 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5819 Register value = locs()->in(0).reg(); 5578 Register value = locs()->in(0).reg();
5820 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi, 5579 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi,
5821 licm_hoisted_ ? ICData::kHoisted : 0); 5580 licm_hoisted_ ? ICData::kHoisted : 0);
5822 __ BranchIfNotSmi(value, deopt); 5581 __ BranchIfNotSmi(value, deopt);
5823 } 5582 }
5824 5583
5825
5826 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, 5584 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
5827 bool opt) const { 5585 bool opt) const {
5828 const intptr_t kNumInputs = 1; 5586 const intptr_t kNumInputs = 1;
5829 const intptr_t kNumTemps = 0; 5587 const intptr_t kNumTemps = 0;
5830 LocationSummary* summary = new (zone) 5588 LocationSummary* summary = new (zone)
5831 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5589 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5832 summary->set_in(0, cids_.IsSingleCid() ? Location::RequiresRegister() 5590 summary->set_in(0, cids_.IsSingleCid() ? Location::RequiresRegister()
5833 : Location::WritableRegister()); 5591 : Location::WritableRegister());
5834 return summary; 5592 return summary;
5835 } 5593 }
5836 5594
5837
5838 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5595 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5839 Register value = locs()->in(0).reg(); 5596 Register value = locs()->in(0).reg();
5840 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); 5597 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass);
5841 if (cids_.IsSingleCid()) { 5598 if (cids_.IsSingleCid()) {
5842 __ cmpl(value, Immediate(Smi::RawValue(cids_.cid_start))); 5599 __ cmpl(value, Immediate(Smi::RawValue(cids_.cid_start)));
5843 __ j(NOT_ZERO, deopt); 5600 __ j(NOT_ZERO, deopt);
5844 } else { 5601 } else {
5845 __ AddImmediate(value, Immediate(-Smi::RawValue(cids_.cid_start))); 5602 __ AddImmediate(value, Immediate(-Smi::RawValue(cids_.cid_start)));
5846 __ cmpl(value, Immediate(Smi::RawValue(cids_.Extent()))); 5603 __ cmpl(value, Immediate(Smi::RawValue(cids_.Extent())));
5847 __ j(ABOVE, deopt); 5604 __ j(ABOVE, deopt);
5848 } 5605 }
5849 } 5606 }
5850 5607
5851
5852 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone, 5608 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
5853 bool opt) const { 5609 bool opt) const {
5854 // Only needed for AOT. 5610 // Only needed for AOT.
5855 UNIMPLEMENTED(); 5611 UNIMPLEMENTED();
5856 return NULL; 5612 return NULL;
5857 } 5613 }
5858 5614
5859
5860 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5615 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5861 // Only needed for AOT. 5616 // Only needed for AOT.
5862 UNIMPLEMENTED(); 5617 UNIMPLEMENTED();
5863 } 5618 }
5864 5619
5865
5866 // Length: register or constant. 5620 // Length: register or constant.
5867 // Index: register, constant or stack slot. 5621 // Index: register, constant or stack slot.
5868 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, 5622 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
5869 bool opt) const { 5623 bool opt) const {
5870 const intptr_t kNumInputs = 2; 5624 const intptr_t kNumInputs = 2;
5871 const intptr_t kNumTemps = 0; 5625 const intptr_t kNumTemps = 0;
5872 LocationSummary* locs = new (zone) 5626 LocationSummary* locs = new (zone)
5873 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5627 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5874 if (length()->definition()->IsConstant()) { 5628 if (length()->definition()->IsConstant()) {
5875 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); 5629 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
5876 } else { 5630 } else {
5877 locs->set_in(kLengthPos, Location::PrefersRegister()); 5631 locs->set_in(kLengthPos, Location::PrefersRegister());
5878 } 5632 }
5879 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); 5633 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
5880 return locs; 5634 return locs;
5881 } 5635 }
5882 5636
5883
5884 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5637 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5885 uint32_t flags = generalized_ ? ICData::kGeneralized : 0; 5638 uint32_t flags = generalized_ ? ICData::kGeneralized : 0;
5886 flags |= licm_hoisted_ ? ICData::kHoisted : 0; 5639 flags |= licm_hoisted_ ? ICData::kHoisted : 0;
5887 Label* deopt = 5640 Label* deopt =
5888 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckArrayBound, flags); 5641 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckArrayBound, flags);
5889 5642
5890 Location length_loc = locs()->in(kLengthPos); 5643 Location length_loc = locs()->in(kLengthPos);
5891 Location index_loc = locs()->in(kIndexPos); 5644 Location index_loc = locs()->in(kIndexPos);
5892 5645
5893 if (length_loc.IsConstant() && index_loc.IsConstant()) { 5646 if (length_loc.IsConstant() && index_loc.IsConstant()) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5936 Register index = index_loc.reg(); 5689 Register index = index_loc.reg();
5937 Register length = length_loc.reg(); 5690 Register length = length_loc.reg();
5938 if (index_cid != kSmiCid) { 5691 if (index_cid != kSmiCid) {
5939 __ BranchIfNotSmi(index, deopt); 5692 __ BranchIfNotSmi(index, deopt);
5940 } 5693 }
5941 __ cmpl(length, index); 5694 __ cmpl(length, index);
5942 __ j(BELOW_EQUAL, deopt); 5695 __ j(BELOW_EQUAL, deopt);
5943 } 5696 }
5944 } 5697 }
5945 5698
5946
5947 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, 5699 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone,
5948 bool opt) const { 5700 bool opt) const {
5949 const intptr_t kNumInputs = 2; 5701 const intptr_t kNumInputs = 2;
5950 switch (op_kind()) { 5702 switch (op_kind()) {
5951 case Token::kBIT_AND: 5703 case Token::kBIT_AND:
5952 case Token::kBIT_OR: 5704 case Token::kBIT_OR:
5953 case Token::kBIT_XOR: 5705 case Token::kBIT_XOR:
5954 case Token::kADD: 5706 case Token::kADD:
5955 case Token::kSUB: 5707 case Token::kSUB:
5956 case Token::kMUL: { 5708 case Token::kMUL: {
(...skipping 12 matching lines...) Expand all
5969 summary->set_temp(0, Location::RequiresRegister()); 5721 summary->set_temp(0, Location::RequiresRegister());
5970 } 5722 }
5971 return summary; 5723 return summary;
5972 } 5724 }
5973 default: 5725 default:
5974 UNREACHABLE(); 5726 UNREACHABLE();
5975 return NULL; 5727 return NULL;
5976 } 5728 }
5977 } 5729 }
5978 5730
5979
5980 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5731 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5981 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 5732 PairLocation* left_pair = locs()->in(0).AsPairLocation();
5982 Register left_lo = left_pair->At(0).reg(); 5733 Register left_lo = left_pair->At(0).reg();
5983 Register left_hi = left_pair->At(1).reg(); 5734 Register left_hi = left_pair->At(1).reg();
5984 PairLocation* right_pair = locs()->in(1).AsPairLocation(); 5735 PairLocation* right_pair = locs()->in(1).AsPairLocation();
5985 Register right_lo = right_pair->At(0).reg(); 5736 Register right_lo = right_pair->At(0).reg();
5986 Register right_hi = right_pair->At(1).reg(); 5737 Register right_hi = right_pair->At(1).reg();
5987 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 5738 PairLocation* out_pair = locs()->out(0).AsPairLocation();
5988 Register out_lo = out_pair->At(0).reg(); 5739 Register out_lo = out_pair->At(0).reg();
5989 Register out_hi = out_pair->At(1).reg(); 5740 Register out_hi = out_pair->At(1).reg();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
6039 __ imull(right_lo); // Result in EDX:EAX. 5790 __ imull(right_lo); // Result in EDX:EAX.
6040 ASSERT(out_lo == EAX); 5791 ASSERT(out_lo == EAX);
6041 ASSERT(out_hi == EDX); 5792 ASSERT(out_hi == EDX);
6042 break; 5793 break;
6043 } 5794 }
6044 default: 5795 default:
6045 UNREACHABLE(); 5796 UNREACHABLE();
6046 } 5797 }
6047 } 5798 }
6048 5799
6049
6050 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, 5800 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone,
6051 bool opt) const { 5801 bool opt) const {
6052 const intptr_t kNumInputs = 2; 5802 const intptr_t kNumInputs = 2;
6053 const intptr_t kNumTemps = 5803 const intptr_t kNumTemps =
6054 (op_kind() == Token::kSHL) && CanDeoptimize() ? 2 : 0; 5804 (op_kind() == Token::kSHL) && CanDeoptimize() ? 2 : 0;
6055 LocationSummary* summary = new (zone) 5805 LocationSummary* summary = new (zone)
6056 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5806 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6057 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5807 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6058 Location::RequiresRegister())); 5808 Location::RequiresRegister()));
6059 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); 5809 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
6060 if ((op_kind() == Token::kSHL) && CanDeoptimize()) { 5810 if ((op_kind() == Token::kSHL) && CanDeoptimize()) {
6061 summary->set_temp(0, Location::RequiresRegister()); 5811 summary->set_temp(0, Location::RequiresRegister());
6062 summary->set_temp(1, Location::RequiresRegister()); 5812 summary->set_temp(1, Location::RequiresRegister());
6063 } 5813 }
6064 summary->set_out(0, Location::SameAsFirstInput()); 5814 summary->set_out(0, Location::SameAsFirstInput());
6065 return summary; 5815 return summary;
6066 } 5816 }
6067 5817
6068
6069 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5818 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6070 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 5819 PairLocation* left_pair = locs()->in(0).AsPairLocation();
6071 Register left_lo = left_pair->At(0).reg(); 5820 Register left_lo = left_pair->At(0).reg();
6072 Register left_hi = left_pair->At(1).reg(); 5821 Register left_hi = left_pair->At(1).reg();
6073 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 5822 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6074 Register out_lo = out_pair->At(0).reg(); 5823 Register out_lo = out_pair->At(0).reg();
6075 Register out_hi = out_pair->At(1).reg(); 5824 Register out_hi = out_pair->At(1).reg();
6076 ASSERT(out_lo == left_lo); 5825 ASSERT(out_lo == left_lo);
6077 ASSERT(out_hi == left_hi); 5826 ASSERT(out_hi == left_hi);
6078 5827
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
6231 } 5980 }
6232 break; 5981 break;
6233 } 5982 }
6234 default: 5983 default:
6235 UNREACHABLE(); 5984 UNREACHABLE();
6236 } 5985 }
6237 __ Bind(&done); 5986 __ Bind(&done);
6238 } 5987 }
6239 } 5988 }
6240 5989
6241
6242 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, 5990 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone,
6243 bool opt) const { 5991 bool opt) const {
6244 const intptr_t kNumInputs = 1; 5992 const intptr_t kNumInputs = 1;
6245 const intptr_t kNumTemps = 0; 5993 const intptr_t kNumTemps = 0;
6246 LocationSummary* summary = new (zone) 5994 LocationSummary* summary = new (zone)
6247 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5995 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6248 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5996 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6249 Location::RequiresRegister())); 5997 Location::RequiresRegister()));
6250 summary->set_out(0, Location::SameAsFirstInput()); 5998 summary->set_out(0, Location::SameAsFirstInput());
6251 return summary; 5999 return summary;
6252 } 6000 }
6253 6001
6254
6255 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6002 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6256 ASSERT(op_kind() == Token::kBIT_NOT); 6003 ASSERT(op_kind() == Token::kBIT_NOT);
6257 PairLocation* left_pair = locs()->in(0).AsPairLocation(); 6004 PairLocation* left_pair = locs()->in(0).AsPairLocation();
6258 Register left_lo = left_pair->At(0).reg(); 6005 Register left_lo = left_pair->At(0).reg();
6259 Register left_hi = left_pair->At(1).reg(); 6006 Register left_hi = left_pair->At(1).reg();
6260 PairLocation* out_pair = locs()->out(0).AsPairLocation(); 6007 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6261 Register out_lo = out_pair->At(0).reg(); 6008 Register out_lo = out_pair->At(0).reg();
6262 Register out_hi = out_pair->At(1).reg(); 6009 Register out_hi = out_pair->At(1).reg();
6263 ASSERT(out_lo == left_lo); 6010 ASSERT(out_lo == left_lo);
6264 ASSERT(out_hi == left_hi); 6011 ASSERT(out_hi == left_hi);
6265 __ notl(left_lo); 6012 __ notl(left_lo);
6266 __ notl(left_hi); 6013 __ notl(left_hi);
6267 } 6014 }
6268 6015
6269
6270 CompileType BinaryUint32OpInstr::ComputeType() const { 6016 CompileType BinaryUint32OpInstr::ComputeType() const {
6271 return CompileType::Int(); 6017 return CompileType::Int();
6272 } 6018 }
6273 6019
6274
6275 CompileType ShiftUint32OpInstr::ComputeType() const { 6020 CompileType ShiftUint32OpInstr::ComputeType() const {
6276 return CompileType::Int(); 6021 return CompileType::Int();
6277 } 6022 }
6278 6023
6279
6280 CompileType UnaryUint32OpInstr::ComputeType() const { 6024 CompileType UnaryUint32OpInstr::ComputeType() const {
6281 return CompileType::Int(); 6025 return CompileType::Int();
6282 } 6026 }
6283 6027
6284
6285 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Zone* zone, 6028 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Zone* zone,
6286 bool opt) const { 6029 bool opt) const {
6287 const intptr_t kNumInputs = 2; 6030 const intptr_t kNumInputs = 2;
6288 const intptr_t kNumTemps = 0; 6031 const intptr_t kNumTemps = 0;
6289 LocationSummary* summary = new (zone) 6032 LocationSummary* summary = new (zone)
6290 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6033 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6291 summary->set_in(0, Location::RequiresRegister()); 6034 summary->set_in(0, Location::RequiresRegister());
6292 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); 6035 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
6293 summary->set_out(0, Location::SameAsFirstInput()); 6036 summary->set_out(0, Location::SameAsFirstInput());
6294 return summary; 6037 return summary;
6295 } 6038 }
6296 6039
6297
6298 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6040 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6299 const intptr_t kShifterLimit = 31; 6041 const intptr_t kShifterLimit = 31;
6300 6042
6301 Register left = locs()->in(0).reg(); 6043 Register left = locs()->in(0).reg();
6302 Register out = locs()->out(0).reg(); 6044 Register out = locs()->out(0).reg();
6303 ASSERT(left == out); 6045 ASSERT(left == out);
6304 6046
6305
6306 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); 6047 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
6307 6048
6308 if (locs()->in(1).IsConstant()) { 6049 if (locs()->in(1).IsConstant()) {
6309 // Shifter is constant. 6050 // Shifter is constant.
6310 6051
6311 const Object& constant = locs()->in(1).constant(); 6052 const Object& constant = locs()->in(1).constant();
6312 ASSERT(constant.IsSmi()); 6053 ASSERT(constant.IsSmi());
6313 const intptr_t shift_value = Smi::Cast(constant).Value(); 6054 const intptr_t shift_value = Smi::Cast(constant).Value();
6314 6055
6315
6316 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). 6056 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6317 switch (op_kind()) { 6057 switch (op_kind()) {
6318 case Token::kSHR: 6058 case Token::kSHR:
6319 __ shrl(left, Immediate(shift_value)); 6059 __ shrl(left, Immediate(shift_value));
6320 break; 6060 break;
6321 case Token::kSHL: 6061 case Token::kSHL:
6322 __ shll(left, Immediate(shift_value)); 6062 __ shll(left, Immediate(shift_value));
6323 break; 6063 break;
6324 default: 6064 default:
6325 UNREACHABLE(); 6065 UNREACHABLE();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6359 } 6099 }
6360 6100
6361 __ Bind(&zero); 6101 __ Bind(&zero);
6362 // Shift was greater than 31 bits, just return zero. 6102 // Shift was greater than 31 bits, just return zero.
6363 __ xorl(left, left); 6103 __ xorl(left, left);
6364 6104
6365 // Exit path. 6105 // Exit path.
6366 __ Bind(&done); 6106 __ Bind(&done);
6367 } 6107 }
6368 6108
6369
6370 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Zone* zone, 6109 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Zone* zone,
6371 bool opt) const { 6110 bool opt) const {
6372 const intptr_t kNumInputs = 1; 6111 const intptr_t kNumInputs = 1;
6373 const intptr_t kNumTemps = 0; 6112 const intptr_t kNumTemps = 0;
6374 LocationSummary* summary = new (zone) 6113 LocationSummary* summary = new (zone)
6375 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6114 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6376 summary->set_in(0, Location::RequiresRegister()); 6115 summary->set_in(0, Location::RequiresRegister());
6377 summary->set_out(0, Location::SameAsFirstInput()); 6116 summary->set_out(0, Location::SameAsFirstInput());
6378 return summary; 6117 return summary;
6379 } 6118 }
6380 6119
6381
6382 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6120 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6383 Register out = locs()->out(0).reg(); 6121 Register out = locs()->out(0).reg();
6384 ASSERT(locs()->in(0).reg() == out); 6122 ASSERT(locs()->in(0).reg() == out);
6385 6123
6386 ASSERT(op_kind() == Token::kBIT_NOT); 6124 ASSERT(op_kind() == Token::kBIT_NOT);
6387 6125
6388 __ notl(out); 6126 __ notl(out);
6389 } 6127 }
6390 6128
6391
6392 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, 6129 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone,
6393 bool opt) const { 6130 bool opt) const {
6394 const intptr_t kNumInputs = 1; 6131 const intptr_t kNumInputs = 1;
6395 const intptr_t kNumTemps = 0; 6132 const intptr_t kNumTemps = 0;
6396 LocationSummary* summary = new (zone) 6133 LocationSummary* summary = new (zone)
6397 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6134 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6398 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) && 6135 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) &&
6399 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) { 6136 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) {
6400 summary->set_in(0, Location::RequiresRegister()); 6137 summary->set_in(0, Location::RequiresRegister());
6401 summary->set_out(0, Location::SameAsFirstInput()); 6138 summary->set_out(0, Location::SameAsFirstInput());
6402 } else if (from() == kUnboxedMint) { 6139 } else if (from() == kUnboxedMint) {
6403 summary->set_in( 6140 summary->set_in(
6404 0, Location::Pair(CanDeoptimize() ? Location::WritableRegister() 6141 0, Location::Pair(CanDeoptimize() ? Location::WritableRegister()
6405 : Location::RequiresRegister(), 6142 : Location::RequiresRegister(),
6406 Location::RequiresRegister())); 6143 Location::RequiresRegister()));
6407 summary->set_out(0, Location::RequiresRegister()); 6144 summary->set_out(0, Location::RequiresRegister());
6408 } else if (from() == kUnboxedUint32) { 6145 } else if (from() == kUnboxedUint32) {
6409 summary->set_in(0, Location::RequiresRegister()); 6146 summary->set_in(0, Location::RequiresRegister());
6410 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 6147 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6411 Location::RequiresRegister())); 6148 Location::RequiresRegister()));
6412 } else if (from() == kUnboxedInt32) { 6149 } else if (from() == kUnboxedInt32) {
6413 summary->set_in(0, Location::RegisterLocation(EAX)); 6150 summary->set_in(0, Location::RegisterLocation(EAX));
6414 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), 6151 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
6415 Location::RegisterLocation(EDX))); 6152 Location::RegisterLocation(EDX)));
6416 } 6153 }
6417 return summary; 6154 return summary;
6418 } 6155 }
6419 6156
6420
6421 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6157 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6422 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) { 6158 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) {
6423 // Representations are bitwise equivalent. 6159 // Representations are bitwise equivalent.
6424 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); 6160 ASSERT(locs()->out(0).reg() == locs()->in(0).reg());
6425 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { 6161 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) {
6426 // Representations are bitwise equivalent. 6162 // Representations are bitwise equivalent.
6427 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); 6163 ASSERT(locs()->out(0).reg() == locs()->in(0).reg());
6428 if (CanDeoptimize()) { 6164 if (CanDeoptimize()) {
6429 Label* deopt = 6165 Label* deopt =
6430 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); 6166 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
6466 Register out_lo = out_pair->At(0).reg(); 6202 Register out_lo = out_pair->At(0).reg();
6467 Register out_hi = out_pair->At(1).reg(); 6203 Register out_hi = out_pair->At(1).reg();
6468 ASSERT(locs()->in(0).reg() == EAX); 6204 ASSERT(locs()->in(0).reg() == EAX);
6469 ASSERT(out_lo == EAX && out_hi == EDX); 6205 ASSERT(out_lo == EAX && out_hi == EDX);
6470 __ cdq(); 6206 __ cdq();
6471 } else { 6207 } else {
6472 UNREACHABLE(); 6208 UNREACHABLE();
6473 } 6209 }
6474 } 6210 }
6475 6211
6476
6477 LocationSummary* ThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const { 6212 LocationSummary* ThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const {
6478 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall); 6213 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
6479 } 6214 }
6480 6215
6481
6482 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6216 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6483 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1, 6217 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kThrowRuntimeEntry, 1,
6484 locs()); 6218 locs());
6485 __ int3(); 6219 __ int3();
6486 } 6220 }
6487 6221
6488
6489 LocationSummary* ReThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const { 6222 LocationSummary* ReThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const {
6490 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall); 6223 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
6491 } 6224 }
6492 6225
6493
6494 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6226 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6495 compiler->SetNeedsStackTrace(catch_try_index()); 6227 compiler->SetNeedsStackTrace(catch_try_index());
6496 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry, 6228 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), kReThrowRuntimeEntry,
6497 2, locs()); 6229 2, locs());
6498 __ int3(); 6230 __ int3();
6499 } 6231 }
6500 6232
6501
6502 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const { 6233 LocationSummary* StopInstr::MakeLocationSummary(Zone* zone, bool opt) const {
6503 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall); 6234 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
6504 } 6235 }
6505 6236
6506
6507 void StopInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6237 void StopInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6508 __ Stop(message()); 6238 __ Stop(message());
6509 } 6239 }
6510 6240
6511
6512 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6241 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6513 if (!compiler->CanFallThroughTo(normal_entry())) { 6242 if (!compiler->CanFallThroughTo(normal_entry())) {
6514 __ jmp(compiler->GetJumpLabel(normal_entry())); 6243 __ jmp(compiler->GetJumpLabel(normal_entry()));
6515 } 6244 }
6516 } 6245 }
6517 6246
6518
6519 LocationSummary* GotoInstr::MakeLocationSummary(Zone* zone, bool opt) const { 6247 LocationSummary* GotoInstr::MakeLocationSummary(Zone* zone, bool opt) const {
6520 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall); 6248 return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kNoCall);
6521 } 6249 }
6522 6250
6523
6524 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6251 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6525 if (!compiler->is_optimizing()) { 6252 if (!compiler->is_optimizing()) {
6526 if (FLAG_reorder_basic_blocks) { 6253 if (FLAG_reorder_basic_blocks) {
6527 compiler->EmitEdgeCounter(block()->preorder_number()); 6254 compiler->EmitEdgeCounter(block()->preorder_number());
6528 } 6255 }
6529 // Add a deoptimization descriptor for deoptimizing instructions that 6256 // Add a deoptimization descriptor for deoptimizing instructions that
6530 // may be inserted before this instruction. 6257 // may be inserted before this instruction.
6531 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(), 6258 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, GetDeoptId(),
6532 TokenPosition::kNoSource); 6259 TokenPosition::kNoSource);
6533 } 6260 }
6534 if (HasParallelMove()) { 6261 if (HasParallelMove()) {
6535 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 6262 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
6536 } 6263 }
6537 6264
6538 // We can fall through if the successor is the next block in the list. 6265 // We can fall through if the successor is the next block in the list.
6539 // Otherwise, we need a jump. 6266 // Otherwise, we need a jump.
6540 if (!compiler->CanFallThroughTo(successor())) { 6267 if (!compiler->CanFallThroughTo(successor())) {
6541 __ jmp(compiler->GetJumpLabel(successor())); 6268 __ jmp(compiler->GetJumpLabel(successor()));
6542 } 6269 }
6543 } 6270 }
6544 6271
6545
6546 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone, 6272 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone,
6547 bool opt) const { 6273 bool opt) const {
6548 const intptr_t kNumInputs = 1; 6274 const intptr_t kNumInputs = 1;
6549 const intptr_t kNumTemps = 1; 6275 const intptr_t kNumTemps = 1;
6550 6276
6551 LocationSummary* summary = new (zone) 6277 LocationSummary* summary = new (zone)
6552 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6278 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6553 6279
6554 summary->set_in(0, Location::RequiresRegister()); 6280 summary->set_in(0, Location::RequiresRegister());
6555 summary->set_temp(0, Location::RequiresRegister()); 6281 summary->set_temp(0, Location::RequiresRegister());
6556 6282
6557 return summary; 6283 return summary;
6558 } 6284 }
6559 6285
6560
6561 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6286 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6562 Register target_reg = locs()->temp_slot(0)->reg(); 6287 Register target_reg = locs()->temp_slot(0)->reg();
6563 6288
6564 // Load code object from frame. 6289 // Load code object from frame.
6565 __ movl(target_reg, Address(EBP, kPcMarkerSlotFromFp * kWordSize)); 6290 __ movl(target_reg, Address(EBP, kPcMarkerSlotFromFp * kWordSize));
6566 // Load instructions object (active_instructions and Code::entry_point() may 6291 // Load instructions object (active_instructions and Code::entry_point() may
6567 // not point to this instruction object any more; see Code::DisableDartCode). 6292 // not point to this instruction object any more; see Code::DisableDartCode).
6568 __ movl(target_reg, 6293 __ movl(target_reg,
6569 FieldAddress(target_reg, Code::saved_instructions_offset())); 6294 FieldAddress(target_reg, Code::saved_instructions_offset()));
6570 __ addl(target_reg, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 6295 __ addl(target_reg, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
6571 6296
6572 // Add the offset. 6297 // Add the offset.
6573 Register offset_reg = locs()->in(0).reg(); 6298 Register offset_reg = locs()->in(0).reg();
6574 if (offset()->definition()->representation() == kTagged) { 6299 if (offset()->definition()->representation() == kTagged) {
6575 __ SmiUntag(offset_reg); 6300 __ SmiUntag(offset_reg);
6576 } 6301 }
6577 __ addl(target_reg, offset_reg); 6302 __ addl(target_reg, offset_reg);
6578 6303
6579 // Jump to the absolute address. 6304 // Jump to the absolute address.
6580 __ jmp(target_reg); 6305 __ jmp(target_reg);
6581 } 6306 }
6582 6307
6583
6584 LocationSummary* StrictCompareInstr::MakeLocationSummary(Zone* zone, 6308 LocationSummary* StrictCompareInstr::MakeLocationSummary(Zone* zone,
6585 bool opt) const { 6309 bool opt) const {
6586 const intptr_t kNumInputs = 2; 6310 const intptr_t kNumInputs = 2;
6587 const intptr_t kNumTemps = 0; 6311 const intptr_t kNumTemps = 0;
6588 if (needs_number_check()) { 6312 if (needs_number_check()) {
6589 LocationSummary* locs = new (zone) 6313 LocationSummary* locs = new (zone)
6590 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 6314 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
6591 locs->set_in(0, Location::RegisterLocation(EAX)); 6315 locs->set_in(0, Location::RegisterLocation(EAX));
6592 locs->set_in(1, Location::RegisterLocation(ECX)); 6316 locs->set_in(1, Location::RegisterLocation(ECX));
6593 locs->set_out(0, Location::RegisterLocation(EAX)); 6317 locs->set_out(0, Location::RegisterLocation(EAX));
6594 return locs; 6318 return locs;
6595 } 6319 }
6596 LocationSummary* locs = new (zone) 6320 LocationSummary* locs = new (zone)
6597 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6321 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6598 locs->set_in(0, Location::RegisterOrConstant(left())); 6322 locs->set_in(0, Location::RegisterOrConstant(left()));
6599 // Only one of the inputs can be a constant. Choose register if the first one 6323 // Only one of the inputs can be a constant. Choose register if the first one
6600 // is a constant. 6324 // is a constant.
6601 locs->set_in(1, locs->in(0).IsConstant() 6325 locs->set_in(1, locs->in(0).IsConstant()
6602 ? Location::RequiresRegister() 6326 ? Location::RequiresRegister()
6603 : Location::RegisterOrConstant(right())); 6327 : Location::RegisterOrConstant(right()));
6604 locs->set_out(0, Location::RequiresRegister()); 6328 locs->set_out(0, Location::RequiresRegister());
6605 return locs; 6329 return locs;
6606 } 6330 }
6607 6331
6608
6609 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 6332 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
6610 BranchLabels labels) { 6333 BranchLabels labels) {
6611 Location left = locs()->in(0); 6334 Location left = locs()->in(0);
6612 Location right = locs()->in(1); 6335 Location right = locs()->in(1);
6613 ASSERT(!left.IsConstant() || !right.IsConstant()); 6336 ASSERT(!left.IsConstant() || !right.IsConstant());
6614 Condition true_condition; 6337 Condition true_condition;
6615 if (left.IsConstant()) { 6338 if (left.IsConstant()) {
6616 true_condition = compiler->EmitEqualityRegConstCompare( 6339 true_condition = compiler->EmitEqualityRegConstCompare(
6617 right.reg(), left.constant(), needs_number_check(), token_pos(), 6340 right.reg(), left.constant(), needs_number_check(), token_pos(),
6618 deopt_id_); 6341 deopt_id_);
6619 } else if (right.IsConstant()) { 6342 } else if (right.IsConstant()) {
6620 true_condition = compiler->EmitEqualityRegConstCompare( 6343 true_condition = compiler->EmitEqualityRegConstCompare(
6621 left.reg(), right.constant(), needs_number_check(), token_pos(), 6344 left.reg(), right.constant(), needs_number_check(), token_pos(),
6622 deopt_id_); 6345 deopt_id_);
6623 } else { 6346 } else {
6624 true_condition = compiler->EmitEqualityRegRegCompare( 6347 true_condition = compiler->EmitEqualityRegRegCompare(
6625 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); 6348 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
6626 } 6349 }
6627 if (kind() != Token::kEQ_STRICT) { 6350 if (kind() != Token::kEQ_STRICT) {
6628 ASSERT(kind() == Token::kNE_STRICT); 6351 ASSERT(kind() == Token::kNE_STRICT);
6629 true_condition = NegateCondition(true_condition); 6352 true_condition = NegateCondition(true_condition);
6630 } 6353 }
6631 return true_condition; 6354 return true_condition;
6632 } 6355 }
6633 6356
6634
6635 // Detect pattern when one value is zero and another is a power of 2. 6357 // Detect pattern when one value is zero and another is a power of 2.
6636 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 6358 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
6637 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 6359 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
6638 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 6360 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
6639 } 6361 }
6640 6362
6641
6642 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone, 6363 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
6643 bool opt) const { 6364 bool opt) const {
6644 comparison()->InitializeLocationSummary(zone, opt); 6365 comparison()->InitializeLocationSummary(zone, opt);
6645 // TODO(vegorov): support byte register constraints in the register allocator. 6366 // TODO(vegorov): support byte register constraints in the register allocator.
6646 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX)); 6367 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX));
6647 return comparison()->locs(); 6368 return comparison()->locs();
6648 } 6369 }
6649 6370
6650
6651 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6371 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6652 ASSERT(locs()->out(0).reg() == EDX); 6372 ASSERT(locs()->out(0).reg() == EDX);
6653 6373
6654 // Clear upper part of the out register. We are going to use setcc on it 6374 // Clear upper part of the out register. We are going to use setcc on it
6655 // which is a byte move. 6375 // which is a byte move.
6656 __ xorl(EDX, EDX); 6376 __ xorl(EDX, EDX);
6657 6377
6658 // Emit comparison code. This must not overwrite the result register. 6378 // Emit comparison code. This must not overwrite the result register.
6659 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using 6379 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
6660 // the labels or returning an invalid condition. 6380 // the labels or returning an invalid condition.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
6692 } else { 6412 } else {
6693 __ decl(EDX); 6413 __ decl(EDX);
6694 __ andl(EDX, 6414 __ andl(EDX,
6695 Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value))); 6415 Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)));
6696 if (false_value != 0) { 6416 if (false_value != 0) {
6697 __ addl(EDX, Immediate(Smi::RawValue(false_value))); 6417 __ addl(EDX, Immediate(Smi::RawValue(false_value)));
6698 } 6418 }
6699 } 6419 }
6700 } 6420 }
6701 6421
6702
6703 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, 6422 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
6704 bool opt) const { 6423 bool opt) const {
6705 const intptr_t kNumInputs = 1; 6424 const intptr_t kNumInputs = 1;
6706 const intptr_t kNumTemps = 0; 6425 const intptr_t kNumTemps = 0;
6707 LocationSummary* summary = new (zone) 6426 LocationSummary* summary = new (zone)
6708 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 6427 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
6709 summary->set_in(0, Location::RegisterLocation(EAX)); // Function. 6428 summary->set_in(0, Location::RegisterLocation(EAX)); // Function.
6710 summary->set_out(0, Location::RegisterLocation(EAX)); 6429 summary->set_out(0, Location::RegisterLocation(EAX));
6711 return summary; 6430 return summary;
6712 } 6431 }
6713 6432
6714
6715 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6433 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6716 // Load arguments descriptor. 6434 // Load arguments descriptor.
6717 const intptr_t argument_count = ArgumentCount(); // Includes type args. 6435 const intptr_t argument_count = ArgumentCount(); // Includes type args.
6718 const Array& arguments_descriptor = 6436 const Array& arguments_descriptor =
6719 Array::ZoneHandle(Z, GetArgumentsDescriptor()); 6437 Array::ZoneHandle(Z, GetArgumentsDescriptor());
6720 __ LoadObject(EDX, arguments_descriptor); 6438 __ LoadObject(EDX, arguments_descriptor);
6721 6439
6722 // EBX: Code (compiled code or lazy compile stub). 6440 // EBX: Code (compiled code or lazy compile stub).
6723 ASSERT(locs()->in(0).reg() == EAX); 6441 ASSERT(locs()->in(0).reg() == EAX);
6724 __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset())); 6442 __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
(...skipping 11 matching lines...) Expand all
6736 compiler->AddDeoptIndexAtCall(deopt_id_after); 6454 compiler->AddDeoptIndexAtCall(deopt_id_after);
6737 } 6455 }
6738 // Add deoptimization continuation point after the call and before the 6456 // Add deoptimization continuation point after the call and before the
6739 // arguments are removed. 6457 // arguments are removed.
6740 // In optimized code this descriptor is needed for exception handling. 6458 // In optimized code this descriptor is needed for exception handling.
6741 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, 6459 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after,
6742 token_pos()); 6460 token_pos());
6743 __ Drop(argument_count); 6461 __ Drop(argument_count);
6744 } 6462 }
6745 6463
6746
6747 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone, 6464 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
6748 bool opt) const { 6465 bool opt) const {
6749 return LocationSummary::Make(zone, 1, Location::RequiresRegister(), 6466 return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
6750 LocationSummary::kNoCall); 6467 LocationSummary::kNoCall);
6751 } 6468 }
6752 6469
6753
6754 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6470 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6755 Register value = locs()->in(0).reg(); 6471 Register value = locs()->in(0).reg();
6756 Register result = locs()->out(0).reg(); 6472 Register result = locs()->out(0).reg();
6757 6473
6758 Label done; 6474 Label done;
6759 __ LoadObject(result, Bool::True()); 6475 __ LoadObject(result, Bool::True());
6760 __ CompareRegisters(result, value); 6476 __ CompareRegisters(result, value);
6761 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 6477 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
6762 __ LoadObject(result, Bool::False()); 6478 __ LoadObject(result, Bool::False());
6763 __ Bind(&done); 6479 __ Bind(&done);
6764 } 6480 }
6765 6481
6766
6767 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone, 6482 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
6768 bool opt) const { 6483 bool opt) const {
6769 return MakeCallSummary(zone); 6484 return MakeCallSummary(zone);
6770 } 6485 }
6771 6486
6772
6773 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6487 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6774 const Code& stub = Code::ZoneHandle( 6488 const Code& stub = Code::ZoneHandle(
6775 compiler->zone(), StubCode::GetAllocationStubForClass(cls())); 6489 compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
6776 const StubEntry stub_entry(stub); 6490 const StubEntry stub_entry(stub);
6777 compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther, 6491 compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther,
6778 locs()); 6492 locs());
6779 compiler->AddStubCallTarget(stub); 6493 compiler->AddStubCallTarget(stub);
6780 __ Drop(ArgumentCount()); // Discard arguments. 6494 __ Drop(ArgumentCount()); // Discard arguments.
6781 } 6495 }
6782 6496
6783
6784 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6497 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6785 ASSERT(!compiler->is_optimizing()); 6498 ASSERT(!compiler->is_optimizing());
6786 __ Call(*StubCode::DebugStepCheck_entry()); 6499 __ Call(*StubCode::DebugStepCheck_entry());
6787 compiler->EmitCallsiteMetaData(token_pos(), deopt_id_, stub_kind_, locs()); 6500 compiler->EmitCallsiteMetaData(token_pos(), deopt_id_, stub_kind_, locs());
6788 } 6501 }
6789 6502
6790
6791 } // namespace dart 6503 } // namespace dart
6792 6504
6793 #undef __ 6505 #undef __
6794 6506
6795 #endif // defined TARGET_ARCH_IA32 6507 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_dbc.cc ('k') | runtime/vm/intermediate_language_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698