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

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

Issue 513213002: Generate some intrinsics using our IR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, enable_type_checks); 18 DECLARE_FLAG(bool, enable_type_checks);
19 19
20 20
21 #define __ assembler-> 21 #define __ assembler->
22 22
23 23
24 void Intrinsifier::ObjectArrayLength(Assembler* assembler) { 24 intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
25 __ ldr(R0, Address(SP, 0 * kWordSize));
26 __ ldr(R0, FieldAddress(R0, Array::length_offset()));
27 __ ret();
28 }
29
30
31 void Intrinsifier::ImmutableArrayLength(Assembler* assembler) {
32 ObjectArrayLength(assembler);
33 }
34
35
36 void Intrinsifier::ObjectArrayGetIndexed(Assembler* assembler) {
37 Label fall_through;
38
39 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index
40 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array
41
42 __ tsti(R0, kSmiTagMask);
43 __ b(&fall_through, NE); // Index is not an smi, fall through.
44
45 // Range check.
46 __ ldr(R6, FieldAddress(R1, Array::length_offset()));
47 __ cmp(R0, Operand(R6));
48 __ b(&fall_through, CS);
49
50 ASSERT(kSmiTagShift == 1);
51 // array element at R1 + R0*4 + Array::data_offset - 1
52 __ add(R6, R1, Operand(R0, LSL, 2));
53 __ ldr(R0, FieldAddress(R6, Array::data_offset()));
54 __ ret();
55 __ Bind(&fall_through);
56 }
57
58
59 void Intrinsifier::ImmutableArrayGetIndexed(Assembler* assembler) {
60 ObjectArrayGetIndexed(assembler);
61 }
62 25
63 26
64 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 27 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
65 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 28 const Library& core_lib = Library::Handle(Library::CoreLibrary());
66 const Class& cls = Class::Handle( 29 const Class& cls = Class::Handle(
67 core_lib.LookupClassAllowPrivate(Symbols::_List())); 30 core_lib.LookupClassAllowPrivate(Symbols::_List()));
68 ASSERT(!cls.IsNull()); 31 ASSERT(!cls.IsNull());
69 ASSERT(cls.NumTypeArguments() == 1); 32 ASSERT(cls.NumTypeArguments() == 1);
70 const intptr_t field_offset = cls.type_arguments_field_offset(); 33 const intptr_t field_offset = cls.type_arguments_field_offset();
71 ASSERT(field_offset != Class::kNoTypeArguments); 34 ASSERT(field_offset != Class::kNoTypeArguments);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 130
168 // Set the length field in the growable array object to 0. 131 // Set the length field in the growable array object to 0.
169 __ LoadImmediate(R1, 0, kNoPP); 132 __ LoadImmediate(R1, 0, kNoPP);
170 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); 133 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()));
171 __ ret(); // Returns the newly allocated object in R0. 134 __ ret(); // Returns the newly allocated object in R0.
172 135
173 __ Bind(&fall_through); 136 __ Bind(&fall_through);
174 } 137 }
175 138
176 139
177 void Intrinsifier::GrowableArrayLength(Assembler* assembler) {
178 __ ldr(R0, Address(SP, 0 * kWordSize));
179 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset()));
180 __ ret();
181 }
182
183
184 void Intrinsifier::GrowableArrayCapacity(Assembler* assembler) {
185 __ ldr(R0, Address(SP, 0 * kWordSize));
186 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset()));
187 __ ldr(R0, FieldAddress(R0, Array::length_offset()));
188 __ ret();
189 }
190
191
192 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { 140 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) {
193 Label fall_through; 141 Label fall_through;
194 142
195 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index 143 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index
196 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array 144 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array
197 145
198 __ tsti(R0, kSmiTagMask); 146 __ tsti(R0, kSmiTagMask);
199 __ b(&fall_through, NE); // Index is not an smi, fall through. 147 __ b(&fall_through, NE); // Index is not an smi, fall through.
200 148
201 // Range check. 149 // Range check.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 __ add(R1, R2, Operand(R1, LSL, 2)); 257 __ add(R1, R2, Operand(R1, LSL, 2));
310 __ StoreIntoObject(R2, 258 __ StoreIntoObject(R2,
311 FieldAddress(R1, Array::data_offset()), 259 FieldAddress(R1, Array::data_offset()),
312 R0); 260 R0);
313 __ LoadObject(R0, Object::null_object(), PP); 261 __ LoadObject(R0, Object::null_object(), PP);
314 __ ret(); 262 __ ret();
315 __ Bind(&fall_through); 263 __ Bind(&fall_through);
316 } 264 }
317 265
318 266
319 // Gets the length of a TypedData.
320 void Intrinsifier::TypedDataLength(Assembler* assembler) {
321 __ ldr(R0, Address(SP, 0 * kWordSize));
322 __ ldr(R0, FieldAddress(R0, TypedData::length_offset()));
323 __ ret();
324 }
325
326
327 void Intrinsifier::Uint8ArrayGetIndexed(Assembler* assembler) {
328 Label fall_through;
329 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index.
330 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array.
331 __ tsti(R0, kSmiTagMask);
332 __ b(&fall_through, NE); // Index is not a smi, fall through.
333
334 // Range check.
335 __ ldr(R6, FieldAddress(R1, TypedData::length_offset()));
336 __ cmp(R0, Operand(R6));
337 __ b(&fall_through, CS);
338
339 // Array element at R1 + R0 + TypedData::data_offset - 1.
340 // Untag R0.
341 __ add(R1, R1, Operand(R0, LSR, 1));
342 __ ldr(R0, FieldAddress(R1, TypedData::data_offset()), kUnsignedByte);
343 __ SmiTag(R0);
344 __ ret();
345 __ Bind(&fall_through);
346 }
347
348
349 void Intrinsifier::ExternalUint8ArrayGetIndexed(Assembler* assembler) {
350 Label fall_through;
351
352 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index.
353 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array.
354 __ tsti(R0, kSmiTagMask);
355 __ b(&fall_through, NE); // Index is not a smi, fall through.
356
357 // Range check.
358 __ ldr(R6, FieldAddress(R1, TypedData::length_offset()));
359 __ cmp(R0, Operand(R6));
360 __ b(&fall_through, CS);
361
362 __ ldr(R1, FieldAddress(R1, ExternalTypedData::data_offset()));
363
364 // Untag R0.
365 __ add(R1, R1, Operand(R0, LSR, 1));
366 __ ldr(R0, Address(R1, 0), kUnsignedByte);
367 __ SmiTag(R0);
368 __ ret();
369 __ Bind(&fall_through);
370 }
371
372
373 void Intrinsifier::Float64ArrayGetIndexed(Assembler* assembler) {
374 Label fall_through;
375 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index.
376 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array.
377 __ tsti(R0, kSmiTagMask);
378 __ b(&fall_through, NE); // Index is not a smi, fall through.
379
380 // Range check.
381 __ ldr(R6, FieldAddress(R1, TypedData::length_offset()));
382 __ cmp(R0, Operand(R6));
383 __ b(&fall_through, CS);
384
385 Address element_address =
386 __ ElementAddressForRegIndex(true, // Load.
387 false, // Not external.
388 kTypedDataFloat64ArrayCid, // Cid.
389 8, // Index scale.
390 R1, // Array.
391 R0); // Index.
392
393 __ fldrd(V0, element_address);
394
395 const Class& double_class = Class::Handle(
396 Isolate::Current()->object_store()->double_class());
397 __ TryAllocate(double_class,
398 &fall_through,
399 R0, // Result register.
400 R1, // Temp register.
401 kNoPP);
402 __ StoreDFieldToOffset(V0, R0, Double::value_offset(), kNoPP);
403 __ ret();
404 __ Bind(&fall_through);
405 }
406
407
408 void Intrinsifier::Float64ArraySetIndexed(Assembler* assembler) {
409 Label fall_through;
410 __ ldr(R0, Address(SP, + 1 * kWordSize)); // Index.
411 __ ldr(R1, Address(SP, + 2 * kWordSize)); // Array.
412 __ tsti(R0, kSmiTagMask);
413 __ b(&fall_through, NE); // Index is not a smi, fall through.
414
415 // Range check.
416 __ ldr(R6, FieldAddress(R1, TypedData::length_offset()));
417 __ cmp(R0, Operand(R6));
418 __ b(&fall_through, CS);
419
420 __ ldr(R2, Address(SP, + 0 * kWordSize)); // Value.
421 __ tsti(R2, kSmiTagMask);
422 __ b(&fall_through, EQ); // Value is Smi, fall through.
423
424 __ LoadClassId(R3, R2, kNoPP);
425 __ CompareImmediate(R3, kDoubleCid, kNoPP);
426 __ b(&fall_through, NE); // Not a Double, fall through.
427
428 __ LoadDFieldFromOffset(V0, R2, Double::value_offset(), kNoPP);
429
430 Address element_address =
431 __ ElementAddressForRegIndex(false, // Store.
432 false, // Not external.
433 kTypedDataFloat64ArrayCid, // Cid.
434 8, // Index scale.
435 R1, // Array.
436 R0); // Index.
437 __ fstrd(V0, element_address);
438 __ ret();
439 __ Bind(&fall_through);
440 }
441
442
443 static int GetScaleFactor(intptr_t size) { 267 static int GetScaleFactor(intptr_t size) {
444 switch (size) { 268 switch (size) {
445 case 1: return 0; 269 case 1: return 0;
446 case 2: return 1; 270 case 2: return 1;
447 case 4: return 2; 271 case 4: return 2;
448 case 8: return 3; 272 case 8: return 3;
449 case 16: return 4; 273 case 16: return 4;
450 } 274 }
451 UNREACHABLE(); 275 UNREACHABLE();
452 return -1; 276 return -1;
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 __ ldr(R0, Address(SP, 0 * kWordSize)); 1073 __ ldr(R0, Address(SP, 0 * kWordSize));
1250 __ ldr(R0, FieldAddress(R0, String::hash_offset())); 1074 __ ldr(R0, FieldAddress(R0, String::hash_offset()));
1251 __ CompareRegisters(R0, ZR); 1075 __ CompareRegisters(R0, ZR);
1252 __ b(&fall_through, EQ); 1076 __ b(&fall_through, EQ);
1253 __ ret(); 1077 __ ret();
1254 // Hash not yet computed. 1078 // Hash not yet computed.
1255 __ Bind(&fall_through); 1079 __ Bind(&fall_through);
1256 } 1080 }
1257 1081
1258 1082
1259 void Intrinsifier::StringBaseLength(Assembler* assembler) {
1260 __ ldr(R0, Address(SP, 0 * kWordSize));
1261 __ ldr(R0, FieldAddress(R0, String::length_offset()));
1262 __ ret();
1263 }
1264
1265
1266 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) { 1083 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
1267 Label fall_through, try_two_byte_string; 1084 Label fall_through, try_two_byte_string;
1268 1085
1269 __ ldr(R1, Address(SP, 0 * kWordSize)); // Index. 1086 __ ldr(R1, Address(SP, 0 * kWordSize)); // Index.
1270 __ ldr(R0, Address(SP, 1 * kWordSize)); // String. 1087 __ ldr(R0, Address(SP, 1 * kWordSize)); // String.
1271 __ tsti(R1, kSmiTagMask); 1088 __ tsti(R1, kSmiTagMask);
1272 __ b(&fall_through, NE); // Index is not a Smi. 1089 __ b(&fall_through, NE); // Index is not a Smi.
1273 // Range check. 1090 // Range check.
1274 __ ldr(R2, FieldAddress(R0, String::length_offset())); 1091 __ ldr(R2, FieldAddress(R0, String::length_offset()));
1275 __ cmp(R1, Operand(R2)); 1092 __ cmp(R1, Operand(R2));
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 Isolate* isolate = Isolate::Current(); 1499 Isolate* isolate = Isolate::Current();
1683 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); 1500 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP);
1684 // Set return value to Isolate::current_tag_. 1501 // Set return value to Isolate::current_tag_.
1685 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); 1502 __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
1686 __ ret(); 1503 __ ret();
1687 } 1504 }
1688 1505
1689 } // namespace dart 1506 } // namespace dart
1690 1507
1691 #endif // defined TARGET_ARCH_ARM64 1508 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698