Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
constants_arm64.h
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_CONSTANTS_ARM64_H_
6#define RUNTIME_VM_CONSTANTS_ARM64_H_
7
8#ifndef RUNTIME_VM_CONSTANTS_H_
9#error Do not include constants_arm64.h directly; use constants.h instead.
10#endif
11
12#include "platform/assert.h"
13#include "platform/globals.h"
14#include "platform/utils.h"
15
16#include "vm/constants_base.h"
17
18namespace dart {
19
20// LR register should not be used directly in handwritten assembly patterns,
21// because it might contain return address. Instead use macross CLOBBERS_LR,
22// SPILLS_RETURN_ADDRESS_FROM_LR_TO_REGISTER,
23// RESTORES_RETURN_ADDRESS_FROM_REGISTER_TO_LR, SPILLS_LR_TO_FRAME,
24// RESTORES_LR_FROM_FRAME, READS_RETURN_ADDRESS_FROM_LR,
25// WRITES_RETURN_ADDRESS_TO_LR to get access to LR constant in a checked way.
26//
27// To prevent accidental use of LR constant we rename it to
28// LR_DO_NOT_USE_DIRECTLY (while keeping the code in this file and other files
29// which are permitted to access LR constant the same by defining LR as
30// LR_DO_NOT_USE_DIRECTLY). You can also use LINK_REGISTER if you need
31// to compare LR register code.
32#define LR LR_DO_NOT_USE_DIRECTLY
33
35 R0 = 0,
36 R1 = 1,
37 R2 = 2,
38 R3 = 3,
39 R4 = 4,
40 R5 = 5,
41 R6 = 6,
42 R7 = 7,
43 R8 = 8,
44 R9 = 9,
45 R10 = 10,
46 R11 = 11,
47 R12 = 12,
48 R13 = 13,
49 R14 = 14,
50 R15 = 15, // SP in Dart code.
51 R16 = 16, // IP0 aka TMP
52 R17 = 17, // IP1 aka TMP2
53 R18 = 18, // reserved on iOS, shadow call stack on Fuchsia, TEB on Windows.
54 R19 = 19,
55 R20 = 20,
56 R21 = 21, // DISPATCH_TABLE_REG (AOT only)
57 R22 = 22, // NULL_REG
58 R23 = 23,
59 R24 = 24, // CODE_REG
60 R25 = 25,
61 R26 = 26, // THR
62 R27 = 27, // PP
63 R28 = 28, // HEAP_BITS
64 R29 = 29, // FP
65 R30 = 30, // LR
66 R31 = 31, // ZR, CSP
68 kNoRegister = -1,
70
71 // These registers both use the encoding R31, but to avoid mistakes we give
72 // them different values, and then translate before encoding.
73 CSP = 32,
74 ZR = 33,
75
76 // Aliases.
79 SP = R15,
80 FP = R29,
81 LR = R30, // Note: direct access to this constant is not allowed. See above.
82};
83
85 // v0 Volatile; Parameter/scratch register, result register.
86 V0 = 0,
87 // v1-v7 Volatile; Parameter/scratch register.
88 V1 = 1,
89 V2 = 2,
90 V3 = 3,
91 V4 = 4,
92 V5 = 5,
93 V6 = 6,
94 V7 = 7,
95 // v8-v15 Non-volatile; Scratch registers
96 // Only the bottom 64 bits are non-volatile! [ARM IHI 0055B, 5.1.2]
97 V8 = 8,
98 V9 = 9,
99 V10 = 10,
100 V11 = 11,
101 V12 = 12,
102 V13 = 13,
103 V14 = 14,
104 V15 = 15,
105 // v16-v31 Volatile; Scratch registers.
106 V16 = 16,
107 V17 = 17,
108 V18 = 18,
109 V19 = 19,
110 V20 = 20,
111 V21 = 21,
112 V22 = 22,
113 V23 = 23,
114 V24 = 24,
115 V25 = 25,
116 V26 = 26,
117 V27 = 27,
118 V28 = 28,
119 V29 = 29,
120 V30 = 30,
121 V31 = 31,
124};
125
126// Register alias for floating point scratch register.
128
129// Architecture independent aliases.
130typedef VRegister FpuRegister;
131const FpuRegister FpuTMP = VTMP;
132const int kFpuRegisterSize = 16;
136
137extern const char* const cpu_reg_names[kNumberOfCpuRegisters];
138extern const char* const cpu_reg_abi_names[kNumberOfCpuRegisters];
139extern const char* const fpu_reg_names[kNumberOfFpuRegisters];
140
141// Register aliases.
142const Register TMP = R16; // Used as scratch register by assembler.
143const Register TMP2 = R17;
144const Register PP = R27; // Caches object pool pointer in generated code.
145const Register DISPATCH_TABLE_REG = R21; // Dispatch table register.
146const Register CODE_REG = R24;
147// Set when calling Dart functions in JIT mode, used by LazyCompileStub.
148const Register FUNCTION_REG = R0;
149const Register FPREG = FP; // Frame pointer register.
150const Register SPREG = R15; // Stack pointer register.
151const Register IC_DATA_REG = R5; // ICData/MegamorphicCache register.
152const Register ARGS_DESC_REG = R4; // Arguments descriptor register.
153const Register THR = R26; // Caches current thread in generated code.
156const Register HEAP_BITS = R28; // write_barrier_mask << 32 | heap_base >> 32
157const Register NULL_REG = R22; // Caches NullObject() value.
158#define DART_ASSEMBLER_HAS_NULL_REG 1
159
160// ABI for catch-clause entry point.
163
164// ABI for write barrier stub.
168
169// Common ABI for shared slow path stubs.
170struct SharedSlowPathStubABI {
171 static constexpr Register kResultReg = R0;
172};
173
174// ABI for instantiation stubs.
175struct InstantiationABI {
177 static constexpr Register kInstantiatorTypeArgumentsReg = R2;
178 static constexpr Register kFunctionTypeArgumentsReg = R1;
179 static constexpr Register kResultTypeArgumentsReg = R0;
180 static constexpr Register kResultTypeReg = R0;
181 static constexpr Register kScratchReg = R8;
182};
183
184// Registers in addition to those listed in InstantiationABI used inside the
185// implementation of the InstantiateTypeArguments stubs.
186struct InstantiateTAVInternalRegs {
187 // The set of registers that must be pushed/popped when probing a hash-based
188 // cache due to overlap with the registers in InstantiationABI.
189 static constexpr intptr_t kSavedRegisters = 0;
190
191 // Additional registers used to probe hash-based caches.
192 static constexpr Register kEntryStartReg = R9;
193 static constexpr Register kProbeMaskReg = R7;
194 static constexpr Register kProbeDistanceReg = R6;
195 static constexpr Register kCurrentEntryIndexReg = R10;
196};
197
198// Registers in addition to those listed in TypeTestABI used inside the
199// implementation of type testing stubs that are _not_ preserved.
200struct TTSInternalRegs {
201 static constexpr Register kInstanceTypeArgumentsReg = R7;
202 static constexpr Register kScratchReg = R9;
203 static constexpr Register kSubTypeArgumentReg = R5;
204 static constexpr Register kSuperTypeArgumentReg = R6;
205
206 // Must be pushed/popped whenever generic type arguments are being checked as
207 // they overlap with registers in TypeTestABI.
208 static constexpr intptr_t kSavedTypeArgumentRegisters = 0;
209
210 static constexpr intptr_t kInternalRegisters =
211 ((1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg) |
214};
215
216// Registers in addition to those listed in TypeTestABI used inside the
217// implementation of subtype test cache stubs that are _not_ preserved.
218struct STCInternalRegs {
219 static constexpr Register kInstanceCidOrSignatureReg = R6;
223 static constexpr Register kCacheEntriesEndReg = R11;
225 static constexpr Register kProbeDistanceReg = R13;
226
227 static constexpr intptr_t kInternalRegisters =
233 (1 << kProbeDistanceReg);
234};
235
236// Calling convention when calling TypeTestingStub and SubtypeTestCacheStub.
237struct TypeTestABI {
238 static constexpr Register kInstanceReg = R0;
239 static constexpr Register kDstTypeReg = R8;
240 static constexpr Register kInstantiatorTypeArgumentsReg = R2;
241 static constexpr Register kFunctionTypeArgumentsReg = R1;
242 static constexpr Register kSubtypeTestCacheReg = R3;
243 static constexpr Register kScratchReg = R4;
244
245 // For calls to SubtypeNTestCacheStub. Must be distinct from the registers
246 // listed above.
247 static constexpr Register kSubtypeTestCacheResultReg = R7;
248 // For calls to InstanceOfStub.
249 static constexpr Register kInstanceOfResultReg = kInstanceReg;
250
251 static constexpr intptr_t kPreservedAbiRegisters =
252 (1 << kInstanceReg) | (1 << kDstTypeReg) |
254
255 static constexpr intptr_t kNonPreservedAbiRegisters =
258 (1 << kScratchReg) | (1 << kSubtypeTestCacheResultReg) | (1 << CODE_REG);
259
260 static constexpr intptr_t kAbiRegisters =
262};
263
264// Calling convention when calling AssertSubtypeStub.
265struct AssertSubtypeABI {
266 static constexpr Register kSubTypeReg = R0;
267 static constexpr Register kSuperTypeReg = R8;
268 static constexpr Register kInstantiatorTypeArgumentsReg = R2;
269 static constexpr Register kFunctionTypeArgumentsReg = R1;
270 static constexpr Register kDstNameReg = R3;
271
272 static constexpr intptr_t kAbiRegisters =
273 (1 << kSubTypeReg) | (1 << kSuperTypeReg) |
275 (1 << kDstNameReg);
276
277 // No result register, as AssertSubtype is only run for side effect
278 // (throws if the subtype check fails).
279};
280
281// ABI for InitStaticFieldStub.
282struct InitStaticFieldABI {
283 static constexpr Register kFieldReg = R2;
284 static constexpr Register kResultReg = R0;
285};
286
287// Registers used inside the implementation of InitLateStaticFieldStub.
288struct InitLateStaticFieldInternalRegs {
289 static constexpr Register kAddressReg = R3;
290 static constexpr Register kScratchReg = R4;
291};
292
293// ABI for InitInstanceFieldStub.
294struct InitInstanceFieldABI {
295 static constexpr Register kInstanceReg = R1;
296 static constexpr Register kFieldReg = R2;
297 static constexpr Register kResultReg = R0;
298};
299
300// Registers used inside the implementation of InitLateInstanceFieldStub.
301struct InitLateInstanceFieldInternalRegs {
302 static constexpr Register kAddressReg = R3;
303 static constexpr Register kScratchReg = R4;
304};
305
306// ABI for LateInitializationError stubs.
307struct LateInitializationErrorABI {
308 static constexpr Register kFieldReg = R9;
309};
310
311// ABI for ThrowStub.
312struct ThrowABI {
313 static constexpr Register kExceptionReg = R0;
314};
315
316// ABI for ReThrowStub.
317struct ReThrowABI {
318 static constexpr Register kExceptionReg = R0;
319 static constexpr Register kStackTraceReg = R1;
320};
321
322// ABI for AssertBooleanStub.
323struct AssertBooleanABI {
324 static constexpr Register kObjectReg = R0;
325};
326
327// ABI for RangeErrorStub.
328struct RangeErrorABI {
329 static constexpr Register kLengthReg = R0;
330 static constexpr Register kIndexReg = R1;
331};
332
333// ABI for AllocateObjectStub.
334struct AllocateObjectABI {
335 static constexpr Register kResultReg = R0;
336 static constexpr Register kTypeArgumentsReg = R1;
337 static constexpr Register kTagsReg = R2;
338};
339
340// ABI for AllocateClosureStub.
341struct AllocateClosureABI {
343 static constexpr Register kFunctionReg = R1;
344 static constexpr Register kContextReg = R2;
345 static constexpr Register kInstantiatorTypeArgsReg = R3;
346 static constexpr Register kScratchReg = R4;
347};
348
349// ABI for AllocateMintShared*Stub.
350struct AllocateMintABI {
352 static constexpr Register kTempReg = R1;
353};
354
355// ABI for Allocate{Mint,Double,Float32x4,Float64x2}Stub.
356struct AllocateBoxABI {
358 static constexpr Register kTempReg = R1;
359};
360
361// ABI for AllocateArrayStub.
362struct AllocateArrayABI {
364 static constexpr Register kLengthReg = R2;
365 static constexpr Register kTypeArgumentsReg = R1;
366};
367
368// ABI for AllocateRecordStub.
369struct AllocateRecordABI {
371 static constexpr Register kShapeReg = R1;
372 static constexpr Register kTemp1Reg = R2;
373 static constexpr Register kTemp2Reg = R3;
374};
375
376// ABI for AllocateSmallRecordStub (AllocateRecord2, AllocateRecord2Named,
377// AllocateRecord3, AllocateRecord3Named).
378struct AllocateSmallRecordABI {
380 static constexpr Register kShapeReg = R1;
381 static constexpr Register kValue0Reg = R2;
382 static constexpr Register kValue1Reg = R3;
383 static constexpr Register kValue2Reg = R4;
384 static constexpr Register kTempReg = R5;
385};
386
387// ABI for AllocateTypedDataArrayStub.
388struct AllocateTypedDataArrayABI {
390 static constexpr Register kLengthReg = R4;
391};
392
393// ABI for BoxDoubleStub.
394struct BoxDoubleStubABI {
395 static constexpr FpuRegister kValueReg = V0;
396 static constexpr Register kTempReg = R1;
397 static constexpr Register kResultReg = R0;
398};
399
400// ABI for DoubleToIntegerStub.
401struct DoubleToIntegerStubABI {
402 static constexpr FpuRegister kInputReg = V0;
403 static constexpr Register kRecognizedKindReg = R0;
404 static constexpr Register kResultReg = R0;
405};
406
407// ABI for SuspendStub (AwaitStub, AwaitWithTypeCheckStub, YieldAsyncStarStub,
408// SuspendSyncStarAtStartStub, SuspendSyncStarAtYieldStub).
409struct SuspendStubABI {
410 static constexpr Register kArgumentReg = R0;
411 static constexpr Register kTypeArgsReg = R1; // Can be the same as kTempReg
412 static constexpr Register kTempReg = R1;
413 static constexpr Register kFrameSizeReg = R2;
414 static constexpr Register kSuspendStateReg = R3;
415 static constexpr Register kFunctionDataReg = R4;
416 static constexpr Register kSrcFrameReg = R5;
417 static constexpr Register kDstFrameReg = R6;
418};
419
420// ABI for InitSuspendableFunctionStub (InitAsyncStub, InitAsyncStarStub,
421// InitSyncStarStub).
422struct InitSuspendableFunctionStubABI {
423 static constexpr Register kTypeArgsReg = R0;
424};
425
426// ABI for ResumeStub
427struct ResumeStubABI {
428 static constexpr Register kSuspendStateReg = R2;
429 static constexpr Register kTempReg = R0;
430 // Registers for the frame copying (the 1st part).
431 static constexpr Register kFrameSizeReg = R1;
432 static constexpr Register kSrcFrameReg = R3;
433 static constexpr Register kDstFrameReg = R4;
434 // Registers for control transfer.
435 // (the 2nd part, can reuse registers from the 1st part)
436 static constexpr Register kResumePcReg = R1;
437 // Can also reuse kSuspendStateReg but should not conflict with CODE_REG/PP.
438 static constexpr Register kExceptionReg = R3;
439 static constexpr Register kStackTraceReg = R4;
440};
441
442// ABI for ReturnStub (ReturnAsyncStub, ReturnAsyncNotFutureStub,
443// ReturnAsyncStarStub).
444struct ReturnStubABI {
445 static constexpr Register kSuspendStateReg = R2;
446};
447
448// ABI for AsyncExceptionHandlerStub.
449struct AsyncExceptionHandlerStubABI {
450 static constexpr Register kSuspendStateReg = R2;
451};
452
453// ABI for CloneSuspendStateStub.
454struct CloneSuspendStateStubABI {
455 static constexpr Register kSourceReg = R0;
456 static constexpr Register kDestinationReg = R1;
457 static constexpr Register kTempReg = R2;
458 static constexpr Register kFrameSizeReg = R3;
459 static constexpr Register kSrcFrameReg = R4;
460 static constexpr Register kDstFrameReg = R5;
461};
462
463// ABI for FfiAsyncCallbackSendStub.
464struct FfiAsyncCallbackSendStubABI {
465 static constexpr Register kArgsReg = R0;
466};
467
468// ABI for DispatchTableNullErrorStub and consequently for all dispatch
469// table calls (though normal functions will not expect or use this
470// register). This ABI is added to distinguish memory corruption errors from
471// null errors.
472struct DispatchTableNullErrorABI {
473 static constexpr Register kClassIdReg = R0;
474};
475
476// TODO(regis): Add ABIs for type testing stubs and is-type test stubs instead
477// of reusing the constants of the instantiation stubs ABI.
478
479// Masks, sizes, etc.
480const int kXRegSizeInBits = 64;
481const int kWRegSizeInBits = 32;
482const int64_t kXRegMask = 0xffffffffffffffffL;
483const int64_t kWRegMask = 0x00000000ffffffffL;
484
485// List of registers used in load/store multiple.
486typedef uint32_t RegList;
487const RegList kAllCpuRegistersList = 0xFFFFFFFF;
488const RegList kAllFpuRegistersList = 0xFFFFFFFF;
489
490// See "Procedure Call Standard for the ARM 64-bit Architecture", document
491// number "ARM IHI 0055B", May 22 2013.
492
493#define R(reg) (static_cast<RegList>(1) << (reg))
494
495// C++ ABI call registers.
497 R(R0) | R(R1) | R(R2) | R(R3) | R(R4) | R(R5) | R(R6) | R(R7);
499 R(R10) | R(R11) | R(R12) | R(R13) | R(R14) |
500 R(R15) | R(R16) | R(R17) | R(LR);
501#if defined(DART_TARGET_OS_FUCHSIA)
502// We rely on R18 not being touched by Dart generated assembly or stubs at all.
503// We rely on that any calls into C++ also preserve R18.
504const RegList kAbiPreservedCpuRegs = R(R18) | R(R19) | R(R20) | R(R21) |
505 R(R22) | R(R23) | R(R24) | R(R25) |
506 R(R26) | R(R27) | R(R28);
509const int kAbiPreservedCpuRegCount = 11;
510#else
511const RegList kAbiPreservedCpuRegs = R(R19) | R(R20) | R(R21) | R(R22) |
512 R(R23) | R(R24) | R(R25) | R(R26) |
513 R(R27) | R(R28);
516const int kAbiPreservedCpuRegCount = 10;
517#endif
520const int kAbiPreservedFpuRegCount = 8;
521
522// R18 is reserved on Mac/iOS, Fuchsia, Windows and sometimes Android. Although
523// it is available on Linux, we mark it as reserved unconditionally to avoid
524// adding another dimenision for OS into the extracted runtime offsets.
525const RegList kReservedCpuRegisters = R(SPREG) | // Dart SP
526 R(FPREG) | R(TMP) | R(TMP2) | R(PP) |
527 R(THR) | R(LR) | R(HEAP_BITS) |
528 R(NULL_REG) | R(R31) | // C++ SP
530constexpr intptr_t kNumberOfReservedCpuRegisters =
532// CPU registers available to Dart allocator.
534 kAllCpuRegistersList & ~kReservedCpuRegisters;
535constexpr int kNumberOfDartAvailableCpuRegs =
537// No reason to prefer certain registers on ARM64.
538constexpr int kRegisterAllocationBias = 0;
539// Registers available to Dart that are not preserved by runtime calls.
541 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
544const int kDartVolatileCpuRegCount = 15;
546
548 R(V0) | R(V1) | R(V2) | R(V3) | R(V4) | R(V5) | R(V6) | R(V7) | R(V16) |
549 R(V17) | R(V18) | R(V19) | R(V20) | R(V21) | R(V22) | R(V23) | R(V24) |
550 R(V25) | R(V26) | R(V27) | R(V28) | R(V29) | R(V30) | R(V31);
551
552constexpr int kStoreBufferWrapperSize = 32;
553
554class CallingConventions {
555 public:
556 static constexpr intptr_t kArgumentRegisters = kAbiArgumentCpuRegs;
557 static const Register ArgumentRegisters[];
558 static constexpr intptr_t kNumArgRegs = 8;
559 // The native ABI uses R8 to pass the pointer to the memory preallocated for
560 // struct return values. Arm64 is the only ABI in which this pointer is _not_
561 // in ArgumentRegisters[0] or on the stack.
564
565 static const FpuRegister FpuArgumentRegisters[];
566 static constexpr intptr_t kFpuArgumentRegisters =
567 R(V0) | R(V1) | R(V2) | R(V3) | R(V4) | R(V5) | R(V6) | R(V7);
568 static constexpr intptr_t kNumFpuArgRegs = 8;
569
570 static constexpr bool kArgumentIntRegXorFpuReg = false;
571
572 static constexpr intptr_t kCalleeSaveCpuRegisters = kAbiPreservedCpuRegs;
573
574 // Whether larger than wordsize arguments are aligned to even registers.
579
580 // How stack arguments are aligned.
581#if defined(DART_TARGET_OS_MACOS_IOS) || defined(DART_TARGET_OS_MACOS)
582 // > Function arguments may consume slots on the stack that are not multiples
583 // > of 8 bytes.
584 // https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms
587 // Varargs are aligned to wordsize.
590#else
595#endif
596
597 // How fields in compounds are aligned.
599
600 // Whether 1 or 2 byte-sized arguments or return values are passed extended
601 // to 4 bytes.
602#if defined(DART_TARGET_OS_MACOS_IOS) || defined(DART_TARGET_OS_MACOS)
605#else
608#endif
610
611 static constexpr Register kReturnReg = R0;
612 static constexpr Register kSecondReturnReg = R1;
613 static constexpr FpuRegister kReturnFpuReg = V0;
614
615 static constexpr Register kFfiAnyNonAbiRegister = R19;
616 static constexpr Register kFirstNonArgumentRegister = R9;
617 static constexpr Register kSecondNonArgumentRegister = R10;
618 static constexpr Register kStackPointerRegister = SPREG;
619
623};
624
625// Register based calling convention used for Dart functions.
626//
627// See |compiler::ComputeCallingConvention| for more details.
629 static constexpr Register kCpuRegistersForArgs[] = {R1, R2, R3, R5, R6, R7};
630 static constexpr FpuRegister kFpuRegistersForArgs[] = {V0, V1, V2,
631 V3, V4, V5};
632};
633
634#undef R
635
637 return ((r == ZR) || (r == CSP)) ? R31 : r;
638}
639
640// Values for the condition field as defined in section A3.2.
642 kNoCondition = -1,
643 EQ = 0, // equal
644 NE = 1, // not equal
645 CS = 2, // carry set/unsigned higher or same
646 CC = 3, // carry clear/unsigned lower
647 MI = 4, // minus/negative
648 PL = 5, // plus/positive or zero
649 VS = 6, // overflow
650 VC = 7, // no overflow
651 HI = 8, // unsigned higher
652 LS = 9, // unsigned lower or same
653 GE = 10, // signed greater than or equal
654 LT = 11, // signed less than
655 GT = 12, // signed greater than
656 LE = 13, // signed less than or equal
657 AL = 14, // always (unconditional)
658 NV = 15, // special condition (refer to section C1.2.3)
660
661 // Platform-independent variants declared for all platforms
662 EQUAL = EQ,
663 ZERO = EQUAL,
664 NOT_EQUAL = NE,
666 LESS = LT,
667 LESS_EQUAL = LE,
669 GREATER = GT,
674 OVERFLOW = VS,
675 NO_OVERFLOW = VC,
676
678};
679
681 COMPILE_ASSERT((EQ ^ NE) == 1);
682 COMPILE_ASSERT((CS ^ CC) == 1);
683 COMPILE_ASSERT((MI ^ PL) == 1);
684 COMPILE_ASSERT((VS ^ VC) == 1);
685 COMPILE_ASSERT((HI ^ LS) == 1);
686 COMPILE_ASSERT((GE ^ LT) == 1);
687 COMPILE_ASSERT((GT ^ LE) == 1);
688 COMPILE_ASSERT((AL ^ NV) == 1);
689 ASSERT(c != AL);
691 return static_cast<Condition>(c ^ 1);
692}
693
694enum Bits {
695 B0 = (1 << 0),
696 B1 = (1 << 1),
697 B2 = (1 << 2),
698 B3 = (1 << 3),
699 B4 = (1 << 4),
700 B5 = (1 << 5),
701 B6 = (1 << 6),
702 B7 = (1 << 7),
703 B8 = (1 << 8),
704 B9 = (1 << 9),
705 B10 = (1 << 10),
706 B11 = (1 << 11),
707 B12 = (1 << 12),
708 B13 = (1 << 13),
709 B14 = (1 << 14),
710 B15 = (1 << 15),
711 B16 = (1 << 16),
712 B17 = (1 << 17),
713 B18 = (1 << 18),
714 B19 = (1 << 19),
715 B20 = (1 << 20),
716 B21 = (1 << 21),
717 B22 = (1 << 22),
718 B23 = (1 << 23),
719 B24 = (1 << 24),
720 B25 = (1 << 25),
721 B26 = (1 << 26),
722 B27 = (1 << 27),
723 B28 = (1 << 28),
724 B29 = (1 << 29),
725 B30 = (1 << 30),
726 B31 = (1 << 31),
727};
728
729// Opcodes from C3
730// C3.1.
753
754// C3.2.1
761
762// C.3.2.2
768
769// C3.2.3
777
778// C3.2.4
780 SystemMask = 0xffc00000,
782 HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0,
783 CLREX = SystemFixed | B17 | B16 | B13 | B12 | B11 | B10 | B9 | B8 | B6 | B4 |
784 B3 | B2 | B1 | B0,
785};
786
787// C3.2.5
794
795// C3.2.6
802
803// C3.2.7
811
812// C3.3.5
818
819// C3.3.6
828
835
836// C3.3.7-10
848
849// C3.3.14-16
858
859// C3.4.1
866
867// C3.4.2
876
877// C3.4.4
886
887// C3.4.5
895
896// C3.4.6
903
904// C3.5.1
911
912// C3.5.3
919
920// C3.5.6
929
930// C3.5.7
937
938// C3.5.8
948
949// C3.5.9
964
965// C3.5.10
978
979// C.3.6.5
990
991// C.3.6.16
993 SIMDThreeSameMask = 0x9f200400,
1022};
1023
1024// C.3.6.17
1039
1040// C.3.6.22
1047
1048// C3.6.25
1059
1060// C3.6.26
1069
1070// C3.6.28
1077
1078// C3.6.30
1091
1092#define APPLY_OP_LIST(_V) \
1093 _V(DPImmediate) \
1094 _V(CompareBranch) \
1095 _V(LoadStore) \
1096 _V(DPRegister) \
1097 _V(DPSimd1) \
1098 _V(DPSimd2) \
1099 _V(FP) \
1100 _V(CompareAndBranch) \
1101 _V(ConditionalBranch) \
1102 _V(ExceptionGen) \
1103 _V(System) \
1104 _V(TestAndBranch) \
1105 _V(UnconditionalBranch) \
1106 _V(UnconditionalBranchReg) \
1107 _V(LoadStoreReg) \
1108 _V(LoadStoreRegPair) \
1109 _V(LoadRegLiteral) \
1110 _V(LoadStoreExclusive) \
1111 _V(AtomicMemory) \
1112 _V(AddSubImm) \
1113 _V(Bitfield) \
1114 _V(LogicalImm) \
1115 _V(MoveWide) \
1116 _V(PCRel) \
1117 _V(AddSubShiftExt) \
1118 _V(AddSubWithCarry) \
1119 _V(ConditionalSelect) \
1120 _V(MiscDP1Source) \
1121 _V(MiscDP2Source) \
1122 _V(MiscDP3Source) \
1123 _V(LogicalShift) \
1124 _V(SIMDCopy) \
1125 _V(SIMDThreeSame) \
1126 _V(SIMDTwoReg) \
1127 _V(FPCompare) \
1128 _V(FPOneSource) \
1129 _V(FPTwoSource) \
1130 _V(FPImm) \
1131 _V(FPIntCvt)
1132
1133enum Shift {
1134 kNoShift = -1,
1135 LSL = 0, // Logical shift left
1136 LSR = 1, // Logical shift right
1137 ASR = 2, // Arithmetic shift right
1138 ROR = 3, // Rotate right
1139 kMaxShift = 4,
1140};
1141
1144 UXTB = 0, // Zero extend byte.
1145 UXTH = 1, // Zero extend halfword (16 bits).
1146 UXTW = 2, // Zero extend word (32 bits).
1147 UXTX = 3, // Zero extend doubleword (64 bits).
1148 SXTB = 4, // Sign extend byte.
1149 SXTH = 5, // Sign extend halfword (16 bits).
1150 SXTW = 6, // Sign extend word (32 bits).
1151 SXTX = 7, // Sign extend doubleword (64 bits).
1153};
1154
1159
1160// Constants used for the decoding or encoding of the individual fields of
1161// instructions. Based on the "Figure 3-1 ARM instruction set summary".
1163 // S-bit (modify condition register)
1164 kSShift = 29,
1165 kSBits = 1,
1166
1167 // sf field.
1170
1171 // size field,
1174
1175 // Registers.
1176 kRdShift = 0,
1177 kRdBits = 5,
1178 kRnShift = 5,
1179 kRnBits = 5,
1182 kRmShift = 16,
1183 kRmBits = 5,
1188 kRsShift = 16,
1189 kRsBits = 5,
1190
1191 // V Registers.
1202
1203 // Immediates.
1235 kImm26Mask = 0x03ffffff << kImm26Shift,
1236
1240
1243
1244 // Bitfield immediates.
1251
1254
1255 // Shift and Extend.
1262
1263 // Hint Fields.
1268};
1269
1270// Helper functions for decoding logical immediates.
1271static inline uint64_t RotateRight(uint64_t value,
1272 uint8_t rotate,
1273 uint8_t width) {
1274 ASSERT(width <= 64);
1275 uint8_t right = rotate & 63;
1276 uint8_t left = (width - rotate) & 63;
1277 return ((value & ((1ULL << right) - 1ULL)) << left) | (value >> right);
1278}
1279
1280static inline uint64_t RepeatBitsAcrossReg(uint8_t reg_size,
1281 uint64_t value,
1282 uint8_t width) {
1283 ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
1284 (width == 32));
1285 ASSERT((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits));
1286 uint64_t result = value & ((1ULL << width) - 1ULL);
1287 for (unsigned i = width; i < reg_size; i *= 2) {
1288 result |= (result << i);
1289 }
1290 return result;
1291}
1292
1294 TIMES_1 = 0,
1295 TIMES_2 = 1,
1296 TIMES_4 = 2,
1297 TIMES_8 = 3,
1298 TIMES_16 = 4,
1299// We can't include vm/compiler/runtime_api.h, so just be explicit instead
1300// of using (dart::)kWordSizeLog2.
1301#if defined(TARGET_ARCH_IS_64_BIT)
1302 // Used for Smi-boxed indices.
1303 TIMES_HALF_WORD_SIZE = kInt64SizeLog2 - 1,
1304 // Used for unboxed indices.
1305 TIMES_WORD_SIZE = kInt64SizeLog2,
1306#else
1307#error "Unexpected word size"
1308#endif
1309#if !defined(DART_COMPRESSED_POINTERS)
1310 TIMES_COMPRESSED_WORD_SIZE = TIMES_WORD_SIZE,
1311#else
1312 TIMES_COMPRESSED_WORD_SIZE = TIMES_HALF_WORD_SIZE,
1313#endif
1314 // Used for Smi-boxed indices.
1316};
1317
1318// The class Instr enables access to individual fields defined in the ARM
1319// architecture instruction set encoding as described in figure A3-1.
1320//
1321// Example: Test whether the instruction at ptr sets the condition code bits.
1322//
1323// bool InstructionSetsConditionCodes(byte* ptr) {
1324// Instr* instr = Instr::At(ptr);
1325// int type = instr->TypeField();
1326// return ((type == 0) || (type == 1)) && instr->HasS();
1327// }
1328//
1329class Instr {
1330 public:
1331 enum { kInstrSize = 4, kInstrSizeLog2 = 2, kPCReadOffset = 8 };
1332
1333 enum class WideSize { k32Bits, k64Bits };
1334
1335 static constexpr int32_t kNopInstruction = HINT; // hint #0 === nop.
1336
1337 // Reserved brk and hlt instruction codes.
1338 static constexpr int32_t kBreakPointCode = 0xdeb0; // For breakpoint.
1339 static constexpr int32_t kSimulatorBreakCode =
1340 0xdeb2; // For breakpoint in sim.
1341 static constexpr int32_t kSimulatorRedirectCode = 0xca11; // For redirection.
1342
1343 // Breakpoint instruction filling assembler code buffers in debug mode.
1344 static constexpr int32_t kBreakPointInstruction = // brk(0xdeb0).
1346
1347 // Breakpoint instruction used by the simulator.
1348 // Should be distinct from kBreakPointInstruction and from a typical user
1349 // breakpoint inserted in generated code for debugging, e.g. brk(0).
1350 static constexpr int32_t kSimulatorBreakpointInstruction =
1352
1353 // Runtime call redirection instruction used by the simulator.
1354 static constexpr int32_t kSimulatorRedirectInstruction =
1356
1357 // Read one particular bit out of the instruction bits.
1358 inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
1359
1360 // Read a bit field out of the instruction bits.
1361 inline int Bits(int shift, int count) const {
1362 return (InstructionBits() >> shift) & ((1 << count) - 1);
1363 }
1364
1365 // Get the raw instruction bits.
1366 inline int32_t InstructionBits() const {
1367 return *reinterpret_cast<const int32_t*>(this);
1368 }
1369
1370 // Set the raw instruction bits to value.
1371 inline void SetInstructionBits(int32_t value) {
1372 *reinterpret_cast<int32_t*>(this) = value;
1373 }
1374
1376 Register rd,
1377 uint16_t imm,
1378 int hw,
1379 WideSize sz) {
1380 ASSERT((hw >= 0) && (hw <= 3));
1381 const int32_t size = (sz == WideSize::k64Bits) ? B31 : 0;
1382 SetInstructionBits(op | size | (static_cast<int32_t>(rd) << kRdShift) |
1383 (static_cast<int32_t>(hw) << kHWShift) |
1384 (static_cast<int32_t>(imm) << kImm16Shift));
1385 }
1386
1388 Register rn) {
1389 SetInstructionBits(op | (static_cast<int32_t>(rn) << kRnShift));
1390 }
1391
1392 inline void SetImm12Bits(int32_t orig, int32_t imm12) {
1393 ASSERT((imm12 & 0xfffff000) == 0);
1394 SetInstructionBits((orig & ~kImm12Mask) | (imm12 << kImm12Shift));
1395 }
1396
1397 inline int NField() const { return Bit(22); }
1398 inline int SField() const { return Bit(kSShift); }
1399 inline int SFField() const { return Bit(kSFShift); }
1400 inline int SzField() const { return Bits(kSzShift, kSzBits); }
1401 inline Register RdField() const {
1402 return static_cast<Register>(Bits(kRdShift, kRdBits));
1403 }
1404 inline Register RnField() const {
1405 return static_cast<Register>(Bits(kRnShift, kRnBits));
1406 }
1407 inline Register RaField() const {
1408 return static_cast<Register>(Bits(kRaShift, kRaBits));
1409 }
1410 inline Register RmField() const {
1411 return static_cast<Register>(Bits(kRmShift, kRmBits));
1412 }
1413 inline Register RtField() const {
1414 return static_cast<Register>(Bits(kRtShift, kRtBits));
1415 }
1416 inline Register Rt2Field() const {
1417 return static_cast<Register>(Bits(kRt2Shift, kRt2Bits));
1418 }
1419 inline Register RsField() const {
1420 return static_cast<Register>(Bits(kRsShift, kRsBits));
1421 }
1422
1423 inline VRegister VdField() const {
1424 return static_cast<VRegister>(Bits(kVdShift, kVdBits));
1425 }
1426 inline VRegister VnField() const {
1427 return static_cast<VRegister>(Bits(kVnShift, kVnBits));
1428 }
1429 inline VRegister VmField() const {
1430 return static_cast<VRegister>(Bits(kVmShift, kVmBits));
1431 }
1432 inline VRegister VtField() const {
1433 return static_cast<VRegister>(Bits(kVtShift, kVtBits));
1434 }
1435 inline VRegister Vt2Field() const {
1436 return static_cast<VRegister>(Bits(kVt2Shift, kVt2Bits));
1437 }
1438
1439 // Immediates
1440 inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
1441 inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); }
1442 inline int Imm7Field() const { return Bits(kImm7Shift, kImm7Bits); }
1443 // Sign-extended Imm7Field()
1444 inline int64_t SImm7Field() const {
1445 return (static_cast<int32_t>(Imm7Field()) << 25) >> 25;
1446 }
1447 inline int Imm8Field() const { return Bits(kImm8Shift, kImm8Bits); }
1448 inline int Imm9Field() const { return Bits(kImm9Shift, kImm9Bits); }
1449 // Sign-extended Imm9Field()
1450 inline int64_t SImm9Field() const {
1451 return (static_cast<int32_t>(Imm9Field()) << 23) >> 23;
1452 }
1453
1454 inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
1455 inline int Imm12ShiftField() const {
1457 }
1458
1459 inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
1460 inline int HWField() const { return Bits(kHWShift, kHWBits); }
1461
1462 inline int ImmRField() const { return Bits(kImmRShift, kImmRBits); }
1463 inline int ImmSField() const { return Bits(kImmSShift, kImmSBits); }
1464
1465 inline int Imm14Field() const { return Bits(kImm14Shift, kImm14Bits); }
1466 inline int64_t SImm14Field() const {
1467 return (static_cast<int32_t>(Imm14Field()) << 18) >> 18;
1468 }
1469 inline int Imm19Field() const { return Bits(kImm19Shift, kImm19Bits); }
1470 inline int64_t SImm19Field() const {
1471 return (static_cast<int32_t>(Imm19Field()) << 13) >> 13;
1472 }
1473 inline int Imm26Field() const { return Bits(kImm26Shift, kImm26Bits); }
1474 inline int64_t SImm26Field() const {
1475 return (static_cast<int32_t>(Imm26Field()) << 6) >> 6;
1476 }
1477
1478 inline Condition ConditionField() const {
1479 return static_cast<Condition>(Bits(kCondShift, kCondBits));
1480 }
1482 return static_cast<Condition>(Bits(kSelCondShift, kSelCondBits));
1483 }
1484
1485 // Shift and Extend.
1486 inline bool IsShift() const {
1487 return IsLogicalShiftOp() || (Bit(kAddShiftExtendShift) == 0);
1488 }
1489 inline bool IsExtend() const {
1490 return !IsLogicalShiftOp() && (Bit(kAddShiftExtendShift) == 1);
1491 }
1492 inline Shift ShiftTypeField() const {
1493 return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits));
1494 }
1495 inline Extend ExtendTypeField() const {
1496 return static_cast<Extend>(Bits(kExtendTypeShift, kExtendTypeBits));
1497 }
1498 inline int ShiftAmountField() const { return Imm6Field(); }
1499 inline int ExtShiftAmountField() const { return Imm3Field(); }
1500
1501// Instruction identification.
1502#define IS_OP(op) \
1503 inline bool Is##op##Op() const { \
1504 return ((InstructionBits() & op##Mask) == (op##Fixed & op##Mask)); \
1505 }
1507#undef IS_OP
1508
1509 inline bool HasS() const { return (SField() == 1); }
1510
1511 // Indicate whether Rd can be the CSP or ZR. This does not check that the
1512 // instruction actually has an Rd field.
1513 R31Type RdMode() const {
1514 // The following instructions use CSP as Rd:
1515 // Add/sub (immediate) when not setting the flags.
1516 // Add/sub (extended) when not setting the flags.
1517 // Logical (immediate) when not setting the flags.
1518 // Otherwise, R31 is the ZR.
1519 if (IsAddSubImmOp() || (IsAddSubShiftExtOp() && IsExtend())) {
1520 if (HasS()) {
1521 return R31IsZR;
1522 } else {
1523 return R31IsSP;
1524 }
1525 }
1526 if (IsLogicalImmOp()) {
1527 const int op = Bits(29, 2);
1528 const bool set_flags = op == 3;
1529 if (set_flags) {
1530 return R31IsZR;
1531 } else {
1532 return R31IsSP;
1533 }
1534 }
1535 return R31IsZR;
1536 }
1537
1538 // Indicate whether Rn can be CSP or ZR. This does not check that the
1539 // instruction actually has an Rn field.
1540 R31Type RnMode() const {
1541 // The following instructions use CSP as Rn:
1542 // All loads and stores.
1543 // Add/sub (immediate).
1544 // Add/sub (extended).
1545 // Otherwise, r31 is ZR.
1546 if (IsLoadStoreOp() || IsAddSubImmOp() ||
1547 (IsAddSubShiftExtOp() && IsExtend())) {
1548 return R31IsSP;
1549 }
1550 return R31IsZR;
1551 }
1552
1553 // Logical immediates can't encode zero, so a return value of zero is used to
1554 // indicate a failure case. Specifically, where the constraints on imm_s are
1555 // not met.
1556 uint64_t ImmLogical() {
1557 const uint8_t reg_size = SFField() == 1 ? kXRegSizeInBits : kWRegSizeInBits;
1558 const int64_t n = NField();
1559 const int64_t imm_s = ImmSField();
1560 const int64_t imm_r = ImmRField();
1561
1562 // An integer is constructed from the n, imm_s and imm_r bits according to
1563 // the following table:
1564 //
1565 // N imms immr size S R
1566 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr)
1567 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr)
1568 // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr)
1569 // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr)
1570 // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr)
1571 // 0 11110s xxxxxr 2 UInt(s) UInt(r)
1572 // (s bits must not be all set)
1573 //
1574 // A pattern is constructed of size bits, where the least significant S+1
1575 // bits are set. The pattern is rotated right by R, and repeated across a
1576 // 32 or 64-bit value, depending on destination register width.
1577
1578 if (n == 1) {
1579 if (imm_s == 0x3F) {
1580 return 0;
1581 }
1582 uint64_t bits = (1ULL << (imm_s + 1)) - 1;
1583 return RotateRight(bits, imm_r, 64);
1584 } else {
1585 if ((imm_s >> 1) == 0x1F) {
1586 return 0;
1587 }
1588 for (int width = 0x20; width >= 0x2; width >>= 1) {
1589 if ((imm_s & width) == 0) {
1590 int mask = width - 1;
1591 if ((imm_s & mask) == mask) {
1592 return 0;
1593 }
1594 uint64_t bits = (1ULL << ((imm_s & mask) + 1)) - 1;
1595 return RepeatBitsAcrossReg(
1596 reg_size, RotateRight(bits, imm_r & mask, width), width);
1597 }
1598 }
1599 }
1600 UNREACHABLE();
1601 return 0;
1602 }
1603
1604 static int64_t VFPExpandImm(uint8_t imm8) {
1605 const int64_t sign = static_cast<int64_t>((imm8 & 0x80) >> 7) << 63;
1606 const int64_t hi_exp = static_cast<int64_t>(!((imm8 & 0x40) >> 6)) << 62;
1607 const int64_t mid_exp = (((imm8 & 0x40) >> 6) == 0) ? 0 : (0xffLL << 54);
1608 const int64_t low_exp = static_cast<int64_t>((imm8 & 0x30) >> 4) << 52;
1609 const int64_t frac = static_cast<int64_t>(imm8 & 0x0f) << 48;
1610 return sign | hi_exp | mid_exp | low_exp | frac;
1611 }
1612
1613 // Instructions are read out of a code stream. The only way to get a
1614 // reference to an instruction is to convert a pointer. There is no way
1615 // to allocate or create instances of class Instr.
1616 // Use the At(pc) function to create references to Instr.
1617 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
1618
1619 private:
1620 DISALLOW_ALLOCATION();
1622};
1623
1624const uint64_t kBreakInstructionFiller = 0xD4200000D4200000L; // brk #0; brk #0
1625
1626struct LinkRegister {};
1627
1628constexpr bool operator==(Register r, LinkRegister) {
1629 return r == LR;
1630}
1631
1632constexpr bool operator!=(Register r, LinkRegister lr) {
1633 return !(r == lr);
1634}
1635
1636inline Register ConcreteRegister(LinkRegister) {
1637 return LR;
1638}
1639
1640#undef LR
1641
1642#define LINK_REGISTER (LinkRegister())
1643
1644// There are many different ARM64 CPUs out there with different alignment
1645// requirements which are mostly not very well documented.
1646//
1647// Apple Silicon CPU Optimization Guide explicitly discourages alignment of
1648// branch targets (see section 4.4.3).
1649//
1650// Aligning to 32 seems like a safe bet based on LLVM's implementation:
1651//
1652// https://github.com/llvm/llvm-project/blob/05c1447b3eabe9cc4a27866094e46c57350c5d5a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp#L107
1653//
1654#if defined(DART_TARGET_OS_MACOS_IOS) || defined(DART_TARGET_OS_MACOS)
1655const intptr_t kPreferredLoopAlignment = 1;
1656#else
1657const intptr_t kPreferredLoopAlignment = 32;
1658#endif
1659
1660} // namespace dart
1661
1662#endif // RUNTIME_VM_CONSTANTS_ARM64_H_
int count
static bool rotate(const SkDCubic &cubic, int zero, int index, SkDCubic &rotPath)
static int sign(SkScalar x)
Definition SkPath.cpp:2141
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define UNREACHABLE()
Definition assert.h:248
#define COMPILE_ASSERT(expr)
Definition assert.h:339
static constexpr ExtensionStrategy kArgumentStackExtension
static constexpr Register kSecondReturnReg
static constexpr intptr_t kCalleeSaveCpuRegisters
static constexpr AlignmentStrategy kArgumentRegisterAlignmentVarArgs
static constexpr AlignmentStrategy kFieldAlignment
static const FpuRegister FpuArgumentRegisters[]
static const Register ArgumentRegisters[]
static constexpr bool kArgumentIntRegXorFpuReg
static constexpr intptr_t kFpuArgumentRegisters
static constexpr FpuRegister kReturnFpuReg
static constexpr intptr_t kNumFpuArgRegs
static constexpr Register kPointerToReturnStructRegisterCall
static constexpr Register kFirstNonArgumentRegister
static constexpr Register kFfiAnyNonAbiRegister
static constexpr AlignmentStrategy kArgumentStackAlignmentVarArgs
static constexpr Register kPointerToReturnStructRegisterReturn
static constexpr AlignmentStrategy kArgumentRegisterAlignment
static constexpr ExtensionStrategy kReturnRegisterExtension
COMPILE_ASSERT(((R(kFirstNonArgumentRegister)|R(kSecondNonArgumentRegister)) &(kArgumentRegisters|R(kPointerToReturnStructRegisterCall)))==0)
static constexpr Register kStackPointerRegister
static constexpr Register kReturnReg
static constexpr intptr_t kArgumentRegisters
static constexpr Register kSecondNonArgumentRegister
static constexpr ExtensionStrategy kArgumentRegisterExtension
static constexpr intptr_t kNumArgRegs
static constexpr AlignmentStrategy kArgumentStackAlignment
static Instr * At(uword pc)
Register RnField() const
int Imm9Field() const
int64_t SImm7Field() const
Shift ShiftTypeField() const
bool HasS() const
int Imm19Field() const
static constexpr int32_t kSimulatorBreakCode
Register RaField() const
int ShiftAmountField() const
Register RtField() const
Extend ExtendTypeField() const
Condition SelectConditionField() const
static constexpr int32_t kSimulatorBreakpointInstruction
Register RmField() const
Register RsField() const
VRegister VtField() const
void SetMoveWideBits(MoveWideOp op, Register rd, uint16_t imm, int hw, WideSize sz)
void SetInstructionBits(int32_t value)
static constexpr int32_t kBreakPointInstruction
int Bit(int nr) const
int32_t InstructionBits() const
int Imm12Field() const
void SetImm12Bits(int32_t orig, int32_t imm12)
int HWField() const
int Imm8Field() const
R31Type RdMode() const
int Imm6Field() const
int64_t SImm26Field() const
int Imm12ShiftField() const
int Imm14Field() const
int SFField() const
bool IsShift() const
bool IsExtend() const
int ImmSField() const
VRegister VmField() const
Condition ConditionField() const
int ImmRField() const
int Imm7Field() const
int NField() const
int64_t SImm19Field() const
static int64_t VFPExpandImm(uint8_t imm8)
int Imm16Field() const
int ExtShiftAmountField() const
void SetUnconditionalBranchRegBits(UnconditionalBranchRegOp op, Register rn)
VRegister VnField() const
int Imm26Field() const
int64_t SImm9Field() const
R31Type RnMode() const
static constexpr int32_t kNopInstruction
Register rd() const
VRegister VdField() const
Register RdField() const
static constexpr int32_t kSimulatorRedirectCode
VRegister Vt2Field() const
int Imm3Field() const
int SzField() const
static constexpr int32_t kBreakPointCode
Register Rt2Field() const
uint64_t ImmLogical()
int64_t SImm14Field() const
static constexpr int32_t kSimulatorRedirectInstruction
int SField() const
int Bits(int shift, int count) const
static constexpr int CountOneBits32(uint32_t x)
Definition utils.h:145
#define APPLY_OP_LIST(_V)
#define IS_OP(op)
#define ASSERT(E)
uint8_t value
GAsyncResult * result
#define R(r)
ExtensionStrategy
@ kExtendedTo4
@ kNotExtended
const QRegister kAbiLastPreservedFpuReg
const FpuRegister kNoFpuRegister
const int kXRegSizeInBits
@ CompareAndBranchMask
@ CompareAndBranchFixed
const Register kWriteBarrierSlotReg
const int64_t kWRegMask
constexpr bool operator!=(Register r, LinkRegister lr)
@ TIMES_COMPRESSED_HALF_WORD_SIZE
@ TIMES_COMPRESSED_WORD_SIZE
const Register THR
const int kDartVolatileCpuRegCount
@ MiscDP2SourceMask
@ MiscDP2SourceFixed
static Condition InvertCondition(Condition c)
const RegList kAbiVolatileCpuRegs
static uint64_t RotateRight(uint64_t value, uint8_t rotate, uint8_t width)
const Register kExceptionObjectReg
const RegList kReservedCpuRegisters
const Register kWriteBarrierObjectReg
const VRegister VTMP
const Register NULL_REG
const RegList kAllFpuRegistersList
const Register kWriteBarrierValueReg
@ TestAndBranchMask
@ TestAndBranchFixed
uint16_t RegList
@ DPImmediateFixed
@ CompareBranchFixed
@ DPRegisterFixed
@ DPImmediateMask
@ CompareBranchMask
@ AddSubShiftExtMask
@ AddSubShiftExtFixed
const char *const fpu_reg_names[kNumberOfFpuRegisters]
@ LoadStoreExclusiveFixed
@ LoadStoreExclusiveMask
@ MiscDP1SourceFixed
@ MiscDP1SourceMask
Register ConcreteRegister(LinkRegister)
const FpuRegister FpuTMP
const Register CALLEE_SAVED_TEMP
@ AtomicMemoryFixed
@ AtomicMemoryMask
uintptr_t uword
Definition globals.h:501
@ LogicalShiftMask
@ LogicalShiftFixed
@ LogicalImmFixed
const Register CODE_REG
constexpr uword kBreakInstructionFiller
@ kNoCondition
@ GREATER_EQUAL
@ UNSIGNED_GREATER
@ kInvalidCondition
@ UNSIGNED_GREATER_EQUAL
@ NO_OVERFLOW
@ UNSIGNED_LESS
@ kNumberOfConditions
@ UNSIGNED_LESS_EQUAL
const Register TMP2
const Register kDartLastVolatileCpuReg
const Register ARGS_DESC_REG
const Register kDartFirstVolatileCpuReg
const Register DISPATCH_TABLE_REG
@ kNumberOfCpuRegisters
@ kNoRegister
const int kNumberOfFpuRegisters
@ LoadStoreRegMask
@ LoadStoreRegFixed
const RegList kAbiPreservedCpuRegs
@ LoadStoreRegPairFixed
@ LoadStoreRegPairMask
@ AddSubWithCarryFixed
@ AddSubWithCarryMask
const Register kAbiLastPreservedCpuReg
constexpr bool operator==(Register r, LinkRegister)
constexpr RegList kDartAvailableCpuRegs
@ kNumberOfVRegisters
@ ConditionalBranchFixed
@ ConditionalBranchMask
const Register TMP
@ SIMDThreeSameFixed
@ SIMDThreeSameMask
const int kAbiPreservedCpuRegCount
const RegList kDartVolatileCpuRegs
const Register kAbiFirstPreservedCpuReg
const Register FPREG
InstructionFields
@ kAddShiftExtendBits
@ kAddShiftExtendShift
const intptr_t kStoreBufferWrapperSize
const Register HEAP_BITS
const int kAbiPreservedFpuRegCount
constexpr int kRegisterAllocationBias
const Register FUNCTION_REG
constexpr intptr_t kNumberOfReservedCpuRegisters
const Register IC_DATA_REG
const char *const cpu_reg_names[kNumberOfCpuRegisters]
constexpr intptr_t kInt64SizeLog2
Definition globals.h:452
const int kWRegSizeInBits
const Register PP
const RegList kAbiArgumentCpuRegs
QRegister FpuRegister
const Register kStackTraceObjectReg
@ ConditionalSelectMask
@ ConditionalSelectFixed
const RegList kAllCpuRegistersList
const intptr_t kPreferredLoopAlignment
simd128_value_t fpu_register_t
@ ExceptionGenFixed
@ ExceptionGenMask
const RegList kAbiVolatileFpuRegs
UnconditionalBranchRegOp
@ UnconditionalBranchRegFixed
@ UnconditionalBranchRegMask
static uint64_t RepeatBitsAcrossReg(uint8_t reg_size, uint64_t value, uint8_t width)
const int64_t kXRegMask
const Register CALLEE_SAVED_TEMP2
const int kDartVolatileFpuRegCount
const Register SPREG
AlignmentStrategy
@ kAlignedToValueSize
@ kAlignedToWordSize
UnconditionalBranchOp
@ UnconditionalBranchMask
@ UnconditionalBranchFixed
@ MiscDP3SourceFixed
@ MiscDP3SourceMask
@ LoadRegLiteralFixed
@ LoadRegLiteralMask
const char *const cpu_reg_abi_names[kNumberOfCpuRegisters]
const int kFpuRegisterSize
constexpr int kNumberOfDartAvailableCpuRegs
const QRegister kAbiFirstPreservedFpuReg
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition globals.h:593
int32_t width
static constexpr Register kResultReg
static constexpr Register kLengthReg
static constexpr Register kTypeArgumentsReg
static constexpr Register kResultReg
static constexpr Register kTempReg
static constexpr Register kFunctionReg
static constexpr Register kContextReg
static constexpr Register kResultReg
static constexpr Register kInstantiatorTypeArgsReg
static constexpr Register kScratchReg
static constexpr Register kResultReg
static constexpr Register kTempReg
static constexpr Register kTypeArgumentsReg
static constexpr Register kResultReg
static constexpr Register kTagsReg
static constexpr Register kShapeReg
static constexpr Register kResultReg
static constexpr Register kTemp1Reg
static constexpr Register kTemp2Reg
static constexpr Register kResultReg
static constexpr Register kShapeReg
static constexpr Register kValue2Reg
static constexpr Register kValue0Reg
static constexpr Register kTempReg
static constexpr Register kValue1Reg
static constexpr Register kLengthReg
static constexpr Register kResultReg
static constexpr Register kObjectReg
static constexpr Register kSubTypeReg
static constexpr Register kSuperTypeReg
static constexpr Register kFunctionTypeArgumentsReg
static constexpr intptr_t kAbiRegisters
static constexpr Register kInstantiatorTypeArgumentsReg
static constexpr Register kDstNameReg
static constexpr Register kSuspendStateReg
static constexpr Register kTempReg
static constexpr Register kResultReg
static constexpr FpuRegister kValueReg
static constexpr Register kDestinationReg
static constexpr Register kSrcFrameReg
static constexpr Register kFrameSizeReg
static constexpr Register kSourceReg
static constexpr Register kTempReg
static constexpr Register kDstFrameReg
static constexpr Register kCpuRegistersForArgs[]
static constexpr FpuRegister kFpuRegistersForArgs[]
static constexpr Register kClassIdReg
static constexpr Register kResultReg
static constexpr Register kRecognizedKindReg
static constexpr FpuRegister kInputReg
static constexpr Register kArgsReg
static constexpr Register kFieldReg
static constexpr Register kResultReg
static constexpr Register kInstanceReg
static constexpr Register kAddressReg
static constexpr Register kScratchReg
static constexpr Register kAddressReg
static constexpr Register kScratchReg
static constexpr Register kResultReg
static constexpr Register kFieldReg
static constexpr Register kTypeArgsReg
static constexpr Register kEntryStartReg
static constexpr intptr_t kSavedRegisters
static constexpr Register kCurrentEntryIndexReg
static constexpr Register kProbeMaskReg
static constexpr Register kProbeDistanceReg
static constexpr Register kInstantiatorTypeArgumentsReg
static constexpr Register kScratchReg
static constexpr Register kResultTypeReg
static constexpr Register kUninstantiatedTypeArgumentsReg
static constexpr Register kResultTypeArgumentsReg
static constexpr Register kFunctionTypeArgumentsReg
static constexpr Register kFieldReg
static constexpr Register kLengthReg
static constexpr Register kIndexReg
static constexpr Register kStackTraceReg
static constexpr Register kExceptionReg
static constexpr Register kSrcFrameReg
static constexpr Register kDstFrameReg
static constexpr Register kFrameSizeReg
static constexpr Register kSuspendStateReg
static constexpr Register kExceptionReg
static constexpr Register kTempReg
static constexpr Register kResumePcReg
static constexpr Register kStackTraceReg
static constexpr Register kSuspendStateReg
static constexpr Register kCacheContentsSizeReg
static constexpr Register kInstanceInstantiatorTypeArgumentsReg
static constexpr intptr_t kInternalRegisters
static constexpr Register kInstanceParentFunctionTypeArgumentsReg
static constexpr Register kProbeDistanceReg
static constexpr Register kInstanceCidOrSignatureReg
static constexpr Register kCacheEntriesEndReg
static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg
static constexpr Register kResultReg
static constexpr Register kSrcFrameReg
static constexpr Register kFunctionDataReg
static constexpr Register kSuspendStateReg
static constexpr Register kTempReg
static constexpr Register kArgumentReg
static constexpr Register kDstFrameReg
static constexpr Register kTypeArgsReg
static constexpr Register kFrameSizeReg
static constexpr intptr_t kInternalRegisters
static constexpr intptr_t kSavedTypeArgumentRegisters
static constexpr Register kSuperTypeArgumentReg
static constexpr Register kSubTypeArgumentReg
static constexpr Register kInstanceTypeArgumentsReg
static constexpr Register kScratchReg
static constexpr Register kExceptionReg
static constexpr Register kSubtypeTestCacheReg
static constexpr Register kDstTypeReg
static constexpr Register kInstanceReg
static constexpr Register kFunctionTypeArgumentsReg
static constexpr Register kInstantiatorTypeArgumentsReg
static constexpr intptr_t kNonPreservedAbiRegisters
static constexpr Register kSubtypeTestCacheResultReg
static constexpr intptr_t kPreservedAbiRegisters
static constexpr Register kScratchReg
static constexpr intptr_t kAbiRegisters
static constexpr Register kInstanceOfResultReg