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 
26 namespace art {
27 
28 class Arm64Mir2Lir FINAL : public Mir2Lir {
29  protected:
30   class InToRegStorageArm64Mapper : public InToRegStorageMapper {
31    public:
InToRegStorageArm64Mapper()32     InToRegStorageArm64Mapper() : cur_core_reg_(0), cur_fp_reg_(0) {}
~InToRegStorageArm64Mapper()33     virtual ~InToRegStorageArm64Mapper() {}
34     virtual RegStorage GetNextReg(ShortyArg arg);
Reset()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_;
GetResetedInToRegStorageMapper()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;
TargetReg(SpecialTargetRegister symbolic_reg,WideKind wide_kind)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   }
TargetPtrReg(SpecialTargetRegister symbolic_reg)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 
WideGPRsAreAliases()234   bool WideGPRsAreAliases() const OVERRIDE {
235     return true;  // 64b architecture.
236   }
WideFPRsAreAliases()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    */
As32BitReg(RegStorage reg)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 
Check32BitReg(RegStorage reg)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    */
As64BitReg(RegStorage reg)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 
Check64BitReg(RegStorage reg)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