1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_DEX_QUICK_ARM64_CODEGEN_ARM64_H_
18#define ART_COMPILER_DEX_QUICK_ARM64_CODEGEN_ARM64_H_
19
20#include "arm64_lir.h"
21#include "base/logging.h"
22#include "dex/quick/mir_to_lir.h"
23
24#include <map>
25
26namespace art {
27
28class Arm64Mir2Lir FINAL : public Mir2Lir {
29 protected:
30  class InToRegStorageArm64Mapper : public InToRegStorageMapper {
31   public:
32    InToRegStorageArm64Mapper() : cur_core_reg_(0), cur_fp_reg_(0) {}
33    virtual ~InToRegStorageArm64Mapper() {}
34    virtual RegStorage GetNextReg(ShortyArg arg);
35    virtual void Reset() OVERRIDE {
36      cur_core_reg_ = 0;
37      cur_fp_reg_ = 0;
38    }
39   private:
40    size_t cur_core_reg_;
41    size_t cur_fp_reg_;
42  };
43
44  InToRegStorageArm64Mapper in_to_reg_storage_arm64_mapper_;
45  InToRegStorageMapper* GetResetedInToRegStorageMapper() OVERRIDE {
46    in_to_reg_storage_arm64_mapper_.Reset();
47    return &in_to_reg_storage_arm64_mapper_;
48  }
49
50 public:
51  Arm64Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena);
52
53  // Required for target - codegen helpers.
54  bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src,
55                          RegLocation rl_dest, int lit) OVERRIDE;
56  bool HandleEasyDivRem(Instruction::Code dalvik_opcode, bool is_div,
57                        RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE;
58  bool HandleEasyDivRem64(Instruction::Code dalvik_opcode, bool is_div,
59                          RegLocation rl_src, RegLocation rl_dest, int64_t lit);
60  bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE;
61  void GenMultiplyByConstantFloat(RegLocation rl_dest, RegLocation rl_src1,
62                                  int32_t constant) OVERRIDE;
63  void GenMultiplyByConstantDouble(RegLocation rl_dest, RegLocation rl_src1,
64                                   int64_t constant) OVERRIDE;
65  LIR* CheckSuspendUsingLoad() OVERRIDE;
66  RegStorage LoadHelper(QuickEntrypointEnum trampoline) OVERRIDE;
67  LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
68                    OpSize size, VolatileKind is_volatile) OVERRIDE;
69  LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale,
70                       OpSize size) OVERRIDE;
71  LIR* LoadConstantNoClobber(RegStorage r_dest, int value) OVERRIDE;
72  LIR* LoadConstantWide(RegStorage r_dest, int64_t value) OVERRIDE;
73  LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, OpSize size,
74                     VolatileKind is_volatile) OVERRIDE;
75  LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
76                        OpSize size) OVERRIDE;
77
78  /// @copydoc Mir2Lir::UnconditionallyMarkGCCard(RegStorage)
79  void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE;
80
81  bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE;
82  void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, bool wide)
83      OVERRIDE;
84
85  LIR* OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
86                         int offset, int check_value, LIR* target, LIR** compare) OVERRIDE;
87
88  // Required for target - register utilities.
89  RegStorage TargetReg(SpecialTargetRegister reg) OVERRIDE;
90  RegStorage TargetReg(SpecialTargetRegister symbolic_reg, WideKind wide_kind) OVERRIDE {
91    if (wide_kind == kWide || wide_kind == kRef) {
92      return As64BitReg(TargetReg(symbolic_reg));
93    } else {
94      return Check32BitReg(TargetReg(symbolic_reg));
95    }
96  }
97  RegStorage TargetPtrReg(SpecialTargetRegister symbolic_reg) OVERRIDE {
98    return As64BitReg(TargetReg(symbolic_reg));
99  }
100  RegLocation GetReturnAlt() OVERRIDE;
101  RegLocation GetReturnWideAlt() OVERRIDE;
102  RegLocation LocCReturn() OVERRIDE;
103  RegLocation LocCReturnRef() OVERRIDE;
104  RegLocation LocCReturnDouble() OVERRIDE;
105  RegLocation LocCReturnFloat() OVERRIDE;
106  RegLocation LocCReturnWide() OVERRIDE;
107  ResourceMask GetRegMaskCommon(const RegStorage& reg) const OVERRIDE;
108  void AdjustSpillMask() OVERRIDE;
109  void ClobberCallerSave() OVERRIDE;
110  void FreeCallTemps() OVERRIDE;
111  void LockCallTemps() OVERRIDE;
112  void CompilerInitializeRegAlloc() OVERRIDE;
113
114  // Required for target - miscellaneous.
115  void AssembleLIR() OVERRIDE;
116  void DumpResourceMask(LIR* lir, const ResourceMask& mask, const char* prefix) OVERRIDE;
117  void SetupTargetResourceMasks(LIR* lir, uint64_t flags,
118                                ResourceMask* use_mask, ResourceMask* def_mask) OVERRIDE;
119  const char* GetTargetInstFmt(int opcode) OVERRIDE;
120  const char* GetTargetInstName(int opcode) OVERRIDE;
121  std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr) OVERRIDE;
122  ResourceMask GetPCUseDefEncoding() const OVERRIDE;
123  uint64_t GetTargetInstFlags(int opcode) OVERRIDE;
124  size_t GetInsnSize(LIR* lir) OVERRIDE;
125  bool IsUnconditionalBranch(LIR* lir) OVERRIDE;
126
127  // Get the register class for load/store of a field.
128  RegisterClass RegClassForFieldLoadStore(OpSize size, bool is_volatile) OVERRIDE;
129
130  // Required for target - Dalvik-level generators.
131  void GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
132                      RegLocation lr_shift) OVERRIDE;
133  void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
134                         RegLocation rl_src2, int flags) OVERRIDE;
135  void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index,
136                   RegLocation rl_dest, int scale) OVERRIDE;
137  void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index,
138                   RegLocation rl_src, int scale, bool card_mark) OVERRIDE;
139  void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
140                         RegLocation rl_shift, int flags) OVERRIDE;
141  void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
142                        RegLocation rl_src2) OVERRIDE;
143  void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
144                       RegLocation rl_src2) OVERRIDE;
145  void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
146                RegLocation rl_src2) OVERRIDE;
147  void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
148  bool GenInlinedReverseBits(CallInfo* info, OpSize size) OVERRIDE;
149  bool GenInlinedAbsFloat(CallInfo* info) OVERRIDE;
150  bool GenInlinedAbsDouble(CallInfo* info) OVERRIDE;
151  bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object) OVERRIDE;
152  bool GenInlinedMinMax(CallInfo* info, bool is_min, bool is_long) OVERRIDE;
153  bool GenInlinedMinMaxFP(CallInfo* info, bool is_min, bool is_double) OVERRIDE;
154  bool GenInlinedSqrt(CallInfo* info) OVERRIDE;
155  bool GenInlinedCeil(CallInfo* info) OVERRIDE;
156  bool GenInlinedFloor(CallInfo* info) OVERRIDE;
157  bool GenInlinedRint(CallInfo* info) OVERRIDE;
158  bool GenInlinedRound(CallInfo* info, bool is_double) OVERRIDE;
159  bool GenInlinedPeek(CallInfo* info, OpSize size) OVERRIDE;
160  bool GenInlinedPoke(CallInfo* info, OpSize size) OVERRIDE;
161  bool GenInlinedAbsInt(CallInfo* info) OVERRIDE;
162  bool GenInlinedAbsLong(CallInfo* info) OVERRIDE;
163  bool GenInlinedArrayCopyCharArray(CallInfo* info) OVERRIDE;
164  void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
165  void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
166                      RegLocation rl_src2, int flags) OVERRIDE;
167  RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div)
168      OVERRIDE;
169  RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div)
170      OVERRIDE;
171  void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)  OVERRIDE;
172  void GenDivZeroCheckWide(RegStorage reg) OVERRIDE;
173  void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) OVERRIDE;
174  void GenExitSequence() OVERRIDE;
175  void GenSpecialExitSequence() OVERRIDE;
176  void GenSpecialEntryForSuspend() OVERRIDE;
177  void GenSpecialExitForSuspend() OVERRIDE;
178  void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double) OVERRIDE;
179  void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir) OVERRIDE;
180  void GenSelect(BasicBlock* bb, MIR* mir) OVERRIDE;
181  void GenSelectConst32(RegStorage left_op, RegStorage right_op, ConditionCode code,
182                        int32_t true_val, int32_t false_val, RegStorage rs_dest,
183                        RegisterClass dest_reg_class) OVERRIDE;
184
185  bool GenMemBarrier(MemBarrierKind barrier_kind) OVERRIDE;
186  void GenMonitorEnter(int opt_flags, RegLocation rl_src) OVERRIDE;
187  void GenMonitorExit(int opt_flags, RegLocation rl_src) OVERRIDE;
188  void GenMoveException(RegLocation rl_dest) OVERRIDE;
189  void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit,
190                                     int first_bit, int second_bit) OVERRIDE;
191  void GenNegDouble(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
192  void GenNegFloat(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
193  void GenLargePackedSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src) OVERRIDE;
194  void GenLargeSparseSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src) OVERRIDE;
195  void GenMaddMsubInt(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
196                      RegLocation rl_src3, bool is_sub);
197  void GenMaddMsubLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
198                       RegLocation rl_src3, bool is_sub);
199
200  // Required for target - single operation generators.
201  LIR* OpUnconditionalBranch(LIR* target) OVERRIDE;
202  LIR* OpCmpBranch(ConditionCode cond, RegStorage src1, RegStorage src2, LIR* target) OVERRIDE;
203  LIR* OpCmpImmBranch(ConditionCode cond, RegStorage reg, int check_value, LIR* target) OVERRIDE;
204  LIR* OpCondBranch(ConditionCode cc, LIR* target) OVERRIDE;
205  LIR* OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target) OVERRIDE;
206  LIR* OpFpRegCopy(RegStorage r_dest, RegStorage r_src) OVERRIDE;
207  LIR* OpIT(ConditionCode cond, const char* guide) OVERRIDE;
208  void OpEndIT(LIR* it) OVERRIDE;
209  LIR* OpMem(OpKind op, RegStorage r_base, int disp) OVERRIDE;
210  void OpPcRelLoad(RegStorage reg, LIR* target) OVERRIDE;
211  LIR* OpReg(OpKind op, RegStorage r_dest_src) OVERRIDE;
212  void OpRegCopy(RegStorage r_dest, RegStorage r_src) OVERRIDE;
213  LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) OVERRIDE;
214  LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value) OVERRIDE;
215  LIR* OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) OVERRIDE;
216  LIR* OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type) OVERRIDE;
217  LIR* OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) OVERRIDE;
218  LIR* OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) OVERRIDE;
219  LIR* OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value) OVERRIDE;
220  LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2) OVERRIDE;
221  LIR* OpTestSuspend(LIR* target) OVERRIDE;
222  LIR* OpVldm(RegStorage r_base, int count) OVERRIDE;
223  LIR* OpVstm(RegStorage r_base, int count) OVERRIDE;
224  void OpRegCopyWide(RegStorage dest, RegStorage src) OVERRIDE;
225
226  bool InexpensiveConstantInt(int32_t value) OVERRIDE;
227  bool InexpensiveConstantInt(int32_t value, Instruction::Code opcode) OVERRIDE;
228  bool InexpensiveConstantFloat(int32_t value) OVERRIDE;
229  bool InexpensiveConstantLong(int64_t value) OVERRIDE;
230  bool InexpensiveConstantDouble(int64_t value) OVERRIDE;
231
232  void GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) OVERRIDE;
233
234  bool WideGPRsAreAliases() const OVERRIDE {
235    return true;  // 64b architecture.
236  }
237  bool WideFPRsAreAliases() const OVERRIDE {
238    return true;  // 64b architecture.
239  }
240
241  size_t GetInstructionOffset(LIR* lir) OVERRIDE;
242
243  NextCallInsn GetNextSDCallInsn() OVERRIDE;
244
245  /*
246   * @brief Generate a relative call to the method that will be patched at link time.
247   * @param target_method The MethodReference of the method to be invoked.
248   * @param type How the method will be invoked.
249   * @returns Call instruction
250   */
251  LIR* CallWithLinkerFixup(const MethodReference& target_method, InvokeType type);
252
253  /*
254   * @brief Generate the actual call insn based on the method info.
255   * @param method_info the lowering info for the method call.
256   * @returns Call instruction
257   */
258  virtual LIR* GenCallInsn(const MirMethodLoweringInfo& method_info) OVERRIDE;
259
260  /*
261   * @brief Handle ARM specific literals.
262   */
263  void InstallLiteralPools() OVERRIDE;
264
265  LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) OVERRIDE;
266
267 private:
268  /**
269   * @brief Given register xNN (dNN), returns register wNN (sNN).
270   * @param reg #RegStorage containing a Solo64 input register (e.g. @c x1 or @c d2).
271   * @return A Solo32 with the same register number as the @p reg (e.g. @c w1 or @c s2).
272   * @see As64BitReg
273   */
274  RegStorage As32BitReg(RegStorage reg) {
275    DCHECK(!reg.IsPair());
276    if ((kFailOnSizeError || kReportSizeError) && !reg.Is64Bit()) {
277      if (kFailOnSizeError) {
278        LOG(FATAL) << "Expected 64b register";
279      } else {
280        LOG(WARNING) << "Expected 64b register";
281        return reg;
282      }
283    }
284    RegStorage ret_val = RegStorage(RegStorage::k32BitSolo,
285                                    reg.GetRawBits() & RegStorage::kRegTypeMask);
286    DCHECK_EQ(GetRegInfo(reg)->FindMatchingView(RegisterInfo::k32SoloStorageMask)
287              ->GetReg().GetReg(),
288              ret_val.GetReg());
289    return ret_val;
290  }
291
292  RegStorage Check32BitReg(RegStorage reg) {
293    if ((kFailOnSizeError || kReportSizeError) && !reg.Is32Bit()) {
294      if (kFailOnSizeError) {
295        LOG(FATAL) << "Checked for 32b register";
296      } else {
297        LOG(WARNING) << "Checked for 32b register";
298        return As32BitReg(reg);
299      }
300    }
301    return reg;
302  }
303
304  /**
305   * @brief Given register wNN (sNN), returns register xNN (dNN).
306   * @param reg #RegStorage containing a Solo32 input register (e.g. @c w1 or @c s2).
307   * @return A Solo64 with the same register number as the @p reg (e.g. @c x1 or @c d2).
308   * @see As32BitReg
309   */
310  RegStorage As64BitReg(RegStorage reg) {
311    DCHECK(!reg.IsPair());
312    if ((kFailOnSizeError || kReportSizeError) && !reg.Is32Bit()) {
313      if (kFailOnSizeError) {
314        LOG(FATAL) << "Expected 32b register";
315      } else {
316        LOG(WARNING) << "Expected 32b register";
317        return reg;
318      }
319    }
320    RegStorage ret_val = RegStorage(RegStorage::k64BitSolo,
321                                    reg.GetRawBits() & RegStorage::kRegTypeMask);
322    DCHECK_EQ(GetRegInfo(reg)->FindMatchingView(RegisterInfo::k64SoloStorageMask)
323              ->GetReg().GetReg(),
324              ret_val.GetReg());
325    return ret_val;
326  }
327
328  RegStorage Check64BitReg(RegStorage reg) {
329    if ((kFailOnSizeError || kReportSizeError) && !reg.Is64Bit()) {
330      if (kFailOnSizeError) {
331        LOG(FATAL) << "Checked for 64b register";
332      } else {
333        LOG(WARNING) << "Checked for 64b register";
334        return As64BitReg(reg);
335      }
336    }
337    return reg;
338  }
339
340  int32_t EncodeImmSingle(uint32_t bits);
341  int32_t EncodeImmDouble(uint64_t bits);
342  LIR* LoadFPConstantValue(RegStorage r_dest, int32_t value);
343  LIR* LoadFPConstantValueWide(RegStorage r_dest, int64_t value);
344  void ReplaceFixup(LIR* prev_lir, LIR* orig_lir, LIR* new_lir);
345  void InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir);
346  void AssignDataOffsets();
347  RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2,
348                        bool is_div, int flags) OVERRIDE;
349  RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE;
350  size_t GetLoadStoreSize(LIR* lir);
351
352  bool SmallLiteralDivRem64(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src,
353                            RegLocation rl_dest, int64_t lit);
354
355  uint32_t LinkFixupInsns(LIR* head_lir, LIR* tail_lir, CodeOffset offset);
356  int AssignInsnOffsets();
357  void AssignOffsets();
358  uint8_t* EncodeLIRs(uint8_t* write_pos, LIR* lir);
359
360  // Spill core and FP registers. Returns the SP difference: either spill size, or whole
361  // frame size.
362  int SpillRegs(RegStorage base, uint32_t core_reg_mask, uint32_t fp_reg_mask, int frame_size);
363
364  // Unspill core and FP registers.
365  void UnspillRegs(RegStorage base, uint32_t core_reg_mask, uint32_t fp_reg_mask, int frame_size);
366
367  void GenLongOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
368
369  LIR* OpRegImm64(OpKind op, RegStorage r_dest_src1, int64_t value);
370  LIR* OpRegRegImm64(OpKind op, RegStorage r_dest, RegStorage r_src1, int64_t value);
371
372  LIR* OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_src2, int shift);
373  LIR* OpRegRegRegShift(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2,
374                        int shift);
375  int EncodeShift(int code, int amount);
376
377  LIR* OpRegRegExtend(OpKind op, RegStorage r_dest_src1, RegStorage r_src2,
378                      A64RegExtEncodings ext, uint8_t amount);
379  LIR* OpRegRegRegExtend(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2,
380                         A64RegExtEncodings ext, uint8_t amount);
381  int EncodeExtend(int extend_type, int amount);
382  bool IsExtendEncoding(int encoded_value);
383
384  LIR* LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size);
385  LIR* StoreBaseDispBody(RegStorage r_base, int displacement, RegStorage r_src, OpSize size);
386
387  int EncodeLogicalImmediate(bool is_wide, uint64_t value);
388  uint64_t DecodeLogicalImmediate(bool is_wide, int value);
389  ArmConditionCode ArmConditionEncoding(ConditionCode code);
390
391  // Helper used in the two GenSelect variants.
392  void GenSelect(int32_t left, int32_t right, ConditionCode code, RegStorage rs_dest,
393                 int result_reg_class);
394
395  void GenNotLong(RegLocation rl_dest, RegLocation rl_src);
396  void GenNegLong(RegLocation rl_dest, RegLocation rl_src);
397  void GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
398                     RegLocation rl_src2, bool is_div, int flags);
399
400  static int Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info,
401                                 int state, const MethodReference& target_method,
402                                 uint32_t unused_idx,
403                                 uintptr_t direct_code, uintptr_t direct_method,
404                                 InvokeType type);
405
406  static const A64EncodingMap EncodingMap[kA64Last];
407
408  ArenaVector<LIR*> call_method_insns_;
409  ArenaVector<LIR*> dex_cache_access_insns_;
410
411  int GenDalvikArgsBulkCopy(CallInfo* info, int first, int count) OVERRIDE;
412};
413
414}  // namespace art
415
416#endif  // ART_COMPILER_DEX_QUICK_ARM64_CODEGEN_ARM64_H_
417