14dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze/*
24dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * Copyright (C) 2015 The Android Open Source Project
34dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze *
44dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * Licensed under the Apache License, Version 2.0 (the "License");
54dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * you may not use this file except in compliance with the License.
64dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * You may obtain a copy of the License at
74dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze *
84dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze *      http://www.apache.org/licenses/LICENSE-2.0
94dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze *
104dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * Unless required by applicable law or agreed to in writing, software
114dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * distributed under the License is distributed on an "AS IS" BASIS,
124dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * See the License for the specific language governing permissions and
144dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze * limitations under the License.
154dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze */
164dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
174dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_MIPS64_H_
184dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_MIPS64_H_
194dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
204dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "code_generator.h"
214dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "dex/compiler_enums.h"
224dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "driver/compiler_options.h"
234dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "nodes.h"
244dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "parallel_move_resolver.h"
254dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "utils/mips64/assembler_mips64.h"
264dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
274dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzenamespace art {
284dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzenamespace mips64 {
294dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
304dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze// InvokeDexCallingConvention registers
314dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
324dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr GpuRegister kParameterCoreRegisters[] =
334dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { A1, A2, A3, A4, A5, A6, A7 };
344dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
354dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
364dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr FpuRegister kParameterFpuRegisters[] =
374dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { F13, F14, F15, F16, F17, F18, F19 };
384dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters);
394dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
404dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
414dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze// InvokeRuntimeCallingConvention registers
424dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
434dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr GpuRegister kRuntimeParameterCoreRegisters[] =
444dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { A0, A1, A2, A3, A4, A5, A6, A7 };
454dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kRuntimeParameterCoreRegistersLength =
464dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    arraysize(kRuntimeParameterCoreRegisters);
474dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
484dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr FpuRegister kRuntimeParameterFpuRegisters[] =
494dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { F12, F13, F14, F15, F16, F17, F18, F19 };
504dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kRuntimeParameterFpuRegistersLength =
514dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    arraysize(kRuntimeParameterFpuRegisters);
524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
534dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
544dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr GpuRegister kCoreCalleeSaves[] =
554dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { S0, S1, S2, S3, S4, S5, S6, S7, GP, S8, RA };  // TODO: review
564dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr FpuRegister kFpuCalleeSaves[] =
574dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { F24, F25, F26, F27, F28, F29, F30, F31 };
584dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
594dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass CodeGeneratorMIPS64;
614dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
624dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InvokeDexCallingConvention : public CallingConvention<GpuRegister, FpuRegister> {
634dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConvention()
654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : CallingConvention(kParameterCoreRegisters,
664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kParameterCoreRegistersLength,
674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kParameterFpuRegisters,
684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kParameterFpuRegistersLength,
694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kMips64PointerSize) {}
704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
744dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InvokeDexCallingConventionVisitorMIPS64 : public InvokeDexCallingConventionVisitor {
764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
774dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConventionVisitorMIPS64() {}
784dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  virtual ~InvokeDexCallingConventionVisitorMIPS64() {}
794dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
804dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetNextLocation(Primitive::Type type) OVERRIDE;
814dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
824dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetMethodLocation() const OVERRIDE;
834dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
844dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
854dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConvention calling_convention;
864dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
874dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorMIPS64);
884dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
894dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
904dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InvokeRuntimeCallingConvention : public CallingConvention<GpuRegister, FpuRegister> {
914dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
924dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeRuntimeCallingConvention()
934dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : CallingConvention(kRuntimeParameterCoreRegisters,
944dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kRuntimeParameterCoreRegistersLength,
954dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kRuntimeParameterFpuRegisters,
964dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kRuntimeParameterFpuRegistersLength,
974dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kMips64PointerSize) {}
984dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
994dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetReturnLocation(Primitive::Type return_type);
1004dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1014dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
1024dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
1034dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
1044dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
105e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravleclass FieldAccessCallingConventionMIPS64 : public FieldAccessCallingConvention {
106e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle public:
107e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  FieldAccessCallingConventionMIPS64() {}
108e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
109e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetObjectLocation() const OVERRIDE {
110e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle    return Location::RegisterLocation(A1);
111e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
112e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetFieldIndexLocation() const OVERRIDE {
113e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle    return Location::RegisterLocation(A0);
114e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
115e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetReturnLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
1168c34ec1ede2608eb99a7e26253b6253931dcb7abGoran Jakovljevic    return Location::RegisterLocation(V0);
117e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
11800580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze  Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE {
11900580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze    return Primitive::Is64BitType(type)
12000580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze        ? Location::RegisterLocation(A2)
12100580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze        : (is_instance
12200580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze            ? Location::RegisterLocation(A2)
12300580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze            : Location::RegisterLocation(A1));
124e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
125e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
126e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle    return Location::FpuRegisterLocation(F0);
127e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
128e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
129e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle private:
130e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionMIPS64);
131e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle};
132e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
1334dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass ParallelMoveResolverMIPS64 : public ParallelMoveResolverWithSwap {
1344dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
1354dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  ParallelMoveResolverMIPS64(ArenaAllocator* allocator, CodeGeneratorMIPS64* codegen)
1364dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {}
1374dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1384dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void EmitMove(size_t index) OVERRIDE;
1394dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void EmitSwap(size_t index) OVERRIDE;
1404dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void SpillScratch(int reg) OVERRIDE;
1414dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void RestoreScratch(int reg) OVERRIDE;
1424dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1434dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Exchange(int index1, int index2, bool double_slot);
1444dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1454dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* GetAssembler() const;
1464dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1474dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
1484dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64* const codegen_;
1494dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1504dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverMIPS64);
1514dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
1524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1534dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass SlowPathCodeMIPS64 : public SlowPathCode {
1544dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
1559cd6d378bd573cdc14d049d32bdd22a97fa4d84aDavid Srbecky  explicit SlowPathCodeMIPS64(HInstruction* instruction)
1569cd6d378bd573cdc14d049d32bdd22a97fa4d84aDavid Srbecky      : SlowPathCode(instruction), entry_label_(), exit_label_() {}
1574dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
158a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* GetEntryLabel() { return &entry_label_; }
159a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* GetExitLabel() { return &exit_label_; }
1604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1614dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
162a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label entry_label_;
163a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label exit_label_;
1644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(SlowPathCodeMIPS64);
1664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
1674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass LocationsBuilderMIPS64 : public HGraphVisitor {
1694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
1704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  LocationsBuilderMIPS64(HGraph* graph, CodeGeneratorMIPS64* codegen)
1714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : HGraphVisitor(graph), codegen_(codegen) {}
1724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#define DECLARE_VISIT_INSTRUCTION(name, super)     \
174f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void Visit##name(H##name* instr) OVERRIDE;
1754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
176f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
177f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(DECLARE_VISIT_INSTRUCTION)
1784dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1794dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#undef DECLARE_VISIT_INSTRUCTION
1804dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
181f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void VisitInstruction(HInstruction* instruction) OVERRIDE {
182f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames    LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
183f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames               << " (id " << instruction->GetId() << ")";
184f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  }
185f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames
1864dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
1874dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleInvoke(HInvoke* invoke);
1884dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleBinaryOp(HBinaryOperation* operation);
1895f7b58ea1adfc0639dd605b65f59198d3763f801Vladimir Marko  void HandleCondition(HCondition* instruction);
1904dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleShift(HBinaryOperation* operation);
1914dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
1924dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
1934dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1944dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConventionVisitorMIPS64 parameter_visitor_;
1954dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1964dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64* const codegen_;
1974dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1984dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderMIPS64);
1994dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
2004dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
20142249c3602c3d0243396ee3627ffb5906aa77c1eAart Bikclass InstructionCodeGeneratorMIPS64 : public InstructionCodeGenerator {
2024dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
2034dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InstructionCodeGeneratorMIPS64(HGraph* graph, CodeGeneratorMIPS64* codegen);
2044dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2054dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#define DECLARE_VISIT_INSTRUCTION(name, super)     \
206f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void Visit##name(H##name* instr) OVERRIDE;
2074dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
208f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
209f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(DECLARE_VISIT_INSTRUCTION)
2104dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2114dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#undef DECLARE_VISIT_INSTRUCTION
2124dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
213f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void VisitInstruction(HInstruction* instruction) OVERRIDE {
214f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames    LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
215f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames               << " (id " << instruction->GetId() << ")";
216f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  }
217f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames
2184dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* GetAssembler() const { return assembler_; }
2194dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2204dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
2214dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateClassInitializationCheck(SlowPathCodeMIPS64* slow_path, GpuRegister class_reg);
2224dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateMemoryBarrier(MemBarrierKind kind);
2234dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
2244dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleBinaryOp(HBinaryOperation* operation);
2255f7b58ea1adfc0639dd605b65f59198d3763f801Vladimir Marko  void HandleCondition(HCondition* instruction);
2264dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleShift(HBinaryOperation* operation);
2278ed1826a9da054920f2d39d34dfc7ba43337e4c9Goran Jakovljevic  void HandleFieldSet(HInstruction* instruction,
2288ed1826a9da054920f2d39d34dfc7ba43337e4c9Goran Jakovljevic                      const FieldInfo& field_info,
2298ed1826a9da054920f2d39d34dfc7ba43337e4c9Goran Jakovljevic                      bool value_can_be_null);
2304dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
2314dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateTestAndBranch(HInstruction* instruction,
2320debae7bc89eb05f7a2bf7dccd223318fad7c88dDavid Brazdil                             size_t condition_input_index,
233a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze                             Mips64Label* true_target,
234a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze                             Mips64Label* false_target);
235c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void DivRemOneOrMinusOne(HBinaryOperation* instruction);
236c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void DivRemByPowerOfTwo(HBinaryOperation* instruction);
237c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
238c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void GenerateDivRemIntegral(HBinaryOperation* instruction);
239299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze  void GenerateIntLongCompare(IfCondition cond, bool is64bit, LocationSummary* locations);
240299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze  void GenerateIntLongCompareAndBranch(IfCondition cond,
241299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                       bool is64bit,
242299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                       LocationSummary* locations,
243299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                       Mips64Label* label);
244299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze  void GenerateFpCompareAndBranch(IfCondition cond,
245299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  bool gt_bias,
246299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  Primitive::Type type,
247299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  LocationSummary* locations,
248299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  Mips64Label* label);
249fc6a86ab2b70781e72b807c1798b83829ca7f931David Brazdil  void HandleGoto(HInstruction* got, HBasicBlock* successor);
2504dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2514dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* const assembler_;
2524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64* const codegen_;
2534dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2544dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorMIPS64);
2554dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
2564dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2574dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass CodeGeneratorMIPS64 : public CodeGenerator {
2584dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
2594dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64(HGraph* graph,
2604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                      const Mips64InstructionSetFeatures& isa_features,
261ecc4366670e12b4812ef1653f7c8d52234ca1b1fSerban Constantinescu                      const CompilerOptions& compiler_options,
262ecc4366670e12b4812ef1653f7c8d52234ca1b1fSerban Constantinescu                      OptimizingCompilerStats* stats = nullptr);
2634dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  virtual ~CodeGeneratorMIPS64() {}
2644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateFrameEntry() OVERRIDE;
2664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateFrameExit() OVERRIDE;
2674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Bind(HBasicBlock* block) OVERRIDE;
2694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
270d967266cdfc8011c81ba6e9857a247c4a73bd0fcLazar Trsic  size_t GetWordSize() const OVERRIDE { return kMips64DoublewordSize; }
2714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
272d967266cdfc8011c81ba6e9857a247c4a73bd0fcLazar Trsic  size_t GetFloatingPointSpillSlotSize() const OVERRIDE { return kMips64DoublewordSize; }
2734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
274c393d63aa2b8f6984672fdd4de631bbeff14b6a2Alexandre Rames  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
275a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze    return assembler_.GetLabelLocation(GetLabelOf(block));
2764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
2774dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2784dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; }
2794dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  HGraphVisitor* GetInstructionVisitor() OVERRIDE { return &instruction_visitor_; }
2804dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* GetAssembler() OVERRIDE { return &assembler_; }
281eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  const Mips64Assembler& GetAssembler() const OVERRIDE { return assembler_; }
2824dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2838ed1826a9da054920f2d39d34dfc7ba43337e4c9Goran Jakovljevic  void MarkGCCard(GpuRegister object, GpuRegister value, bool value_can_be_null);
2844dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2854dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Register allocation.
2864dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
28758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil  void SetupBlockedRegisters() const OVERRIDE;
2884dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2894dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id);
2904dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id);
2914dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id);
2924dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id);
2934dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2944dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
2954dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
2964dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2974dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InstructionSet GetInstructionSet() const OVERRIDE { return InstructionSet::kMips64; }
2984dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2994dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  const Mips64InstructionSetFeatures& GetInstructionSetFeatures() const {
3004dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    return isa_features_;
3014dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
3024dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
303a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* GetLabelOf(HBasicBlock* block) const {
304a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze    return CommonGetLabelOf<Mips64Label>(block_labels_, block);
3054dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
3064dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3074dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Initialize() OVERRIDE {
308a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze    block_labels_ = CommonInitializeLabels<Mips64Label>();
3094dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
3104dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3114dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Finalize(CodeAllocator* allocator) OVERRIDE;
3124dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3134dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Code generation helpers.
314e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE;
3154dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
316175dc732c80e6f2afd83209348124df349290ba8Calin Juravle  void MoveConstant(Location destination, int32_t value) OVERRIDE;
317175dc732c80e6f2afd83209348124df349290ba8Calin Juravle
318e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE;
319e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
320e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
3214dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void SwapLocations(Location loc1, Location loc2, Primitive::Type type);
3224dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3234dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Generate code to invoke a runtime entry point.
324175dc732c80e6f2afd83209348124df349290ba8Calin Juravle  void InvokeRuntime(QuickEntrypointEnum entrypoint,
325175dc732c80e6f2afd83209348124df349290ba8Calin Juravle                     HInstruction* instruction,
326175dc732c80e6f2afd83209348124df349290ba8Calin Juravle                     uint32_t dex_pc,
327175dc732c80e6f2afd83209348124df349290ba8Calin Juravle                     SlowPathCode* slow_path) OVERRIDE;
328175dc732c80e6f2afd83209348124df349290ba8Calin Juravle
3294dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void InvokeRuntime(int32_t offset,
3304dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                     HInstruction* instruction,
3314dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                     uint32_t dex_pc,
3324dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                     SlowPathCode* slow_path);
3334dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3344dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; }
3354dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3364dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const { return false; }
3374dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
338cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // Check if the desired_string_load_kind is supported. If it is, return it,
339cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // otherwise return a fall-back kind that should be used instead.
340cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  HLoadString::LoadKind GetSupportedLoadStringKind(
341cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko      HLoadString::LoadKind desired_string_load_kind) OVERRIDE;
342cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
343dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko  // Check if the desired_dispatch_info is supported. If it is, return it,
344dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko  // otherwise return a fall-back info that should be used instead.
345dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko  HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
346dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko      const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
347dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko      MethodReference target_method) OVERRIDE;
348dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko
34985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe  void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
35053afca191ace3d7447b09097f9ea82a513075c52Alexey Frunze  void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
35185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe
35285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe  void MoveFromReturnRegister(Location trg ATTRIBUTE_UNUSED,
35385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe                              Primitive::Type type ATTRIBUTE_UNUSED) OVERRIDE {
3543acee732f9475fbfc6b046e0044b764e7ff5ac01Chris Larsen    UNIMPLEMENTED(FATAL) << "Not implemented on MIPS64";
35585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe  }
3564dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
357c7098ff991bb4e00a800d315d1c36f52a9cb0149David Srbecky  void GenerateNop();
3582ae48182573da7087bffc2873730bc758ec29696Calin Juravle  void GenerateImplicitNullCheck(HNullCheck* instruction);
3592ae48182573da7087bffc2873730bc758ec29696Calin Juravle  void GenerateExplicitNullCheck(HNullCheck* instruction);
360c7098ff991bb4e00a800d315d1c36f52a9cb0149David Srbecky
3614dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
3624dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Labels for each block that will be compiled.
363a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* block_labels_;  // Indexed by block id.
364a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label frame_entry_label_;
3654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  LocationsBuilderMIPS64 location_builder_;
3664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InstructionCodeGeneratorMIPS64 instruction_visitor_;
3674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  ParallelMoveResolverMIPS64 move_resolver_;
3684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler assembler_;
3694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  const Mips64InstructionSetFeatures& isa_features_;
3704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorMIPS64);
3724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
3734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3744dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze}  // namespace mips64
3754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze}  // namespace art
3764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3774dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_MIPS64_H_
378