code_generator_mips64.h revision 299a93993fb8f3efbf0465cf674d80c3bcfdc66c
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// Use a local definition to prevent copying mistakes.
314dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kMips64WordSize = kMips64PointerSize;
324dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
334dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
344dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze// InvokeDexCallingConvention registers
354dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
364dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr GpuRegister kParameterCoreRegisters[] =
374dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { A1, A2, A3, A4, A5, A6, A7 };
384dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
394dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
404dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr FpuRegister kParameterFpuRegisters[] =
414dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { F13, F14, F15, F16, F17, F18, F19 };
424dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters);
434dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
444dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
454dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze// InvokeRuntimeCallingConvention registers
464dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
474dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr GpuRegister kRuntimeParameterCoreRegisters[] =
484dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { A0, A1, A2, A3, A4, A5, A6, A7 };
494dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kRuntimeParameterCoreRegistersLength =
504dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    arraysize(kRuntimeParameterCoreRegisters);
514dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr FpuRegister kRuntimeParameterFpuRegisters[] =
534dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { F12, F13, F14, F15, F16, F17, F18, F19 };
544dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr size_t kRuntimeParameterFpuRegistersLength =
554dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    arraysize(kRuntimeParameterFpuRegisters);
564dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
574dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
584dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr GpuRegister kCoreCalleeSaves[] =
594dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { S0, S1, S2, S3, S4, S5, S6, S7, GP, S8, RA };  // TODO: review
604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzestatic constexpr FpuRegister kFpuCalleeSaves[] =
614dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    { F24, F25, F26, F27, F28, F29, F30, F31 };
624dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
634dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass CodeGeneratorMIPS64;
654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InvokeDexCallingConvention : public CallingConvention<GpuRegister, FpuRegister> {
674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConvention()
694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : CallingConvention(kParameterCoreRegisters,
704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kParameterCoreRegistersLength,
714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kParameterFpuRegisters,
724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kParameterFpuRegistersLength,
734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kMips64PointerSize) {}
744dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
774dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
784dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
794dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InvokeDexCallingConventionVisitorMIPS64 : public InvokeDexCallingConventionVisitor {
804dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
814dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConventionVisitorMIPS64() {}
824dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  virtual ~InvokeDexCallingConventionVisitorMIPS64() {}
834dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
844dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetNextLocation(Primitive::Type type) OVERRIDE;
854dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
864dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetMethodLocation() const OVERRIDE;
874dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
884dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
894dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConvention calling_convention;
904dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
914dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorMIPS64);
924dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
934dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
944dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InvokeRuntimeCallingConvention : public CallingConvention<GpuRegister, FpuRegister> {
954dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
964dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeRuntimeCallingConvention()
974dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : CallingConvention(kRuntimeParameterCoreRegisters,
984dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kRuntimeParameterCoreRegistersLength,
994dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kRuntimeParameterFpuRegisters,
1004dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kRuntimeParameterFpuRegistersLength,
1014dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                          kMips64PointerSize) {}
1024dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1034dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetReturnLocation(Primitive::Type return_type);
1044dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1054dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
1064dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
1074dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
1084dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
109e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravleclass FieldAccessCallingConventionMIPS64 : public FieldAccessCallingConvention {
110e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle public:
111e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  FieldAccessCallingConventionMIPS64() {}
112e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
113e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetObjectLocation() const OVERRIDE {
114e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle    return Location::RegisterLocation(A1);
115e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
116e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetFieldIndexLocation() const OVERRIDE {
117e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle    return Location::RegisterLocation(A0);
118e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
119e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetReturnLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
1208c34ec1ede2608eb99a7e26253b6253931dcb7abGoran Jakovljevic    return Location::RegisterLocation(V0);
121e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
12200580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze  Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE {
12300580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze    return Primitive::Is64BitType(type)
12400580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze        ? Location::RegisterLocation(A2)
12500580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze        : (is_instance
12600580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze            ? Location::RegisterLocation(A2)
12700580bdbbb119a354c94a9c19928c1dcbd14a8f4Alexey Frunze            : Location::RegisterLocation(A1));
128e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
129e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
130e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle    return Location::FpuRegisterLocation(F0);
131e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  }
132e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
133e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle private:
134e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionMIPS64);
135e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle};
136e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
1374dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass ParallelMoveResolverMIPS64 : public ParallelMoveResolverWithSwap {
1384dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
1394dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  ParallelMoveResolverMIPS64(ArenaAllocator* allocator, CodeGeneratorMIPS64* codegen)
1404dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {}
1414dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1424dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void EmitMove(size_t index) OVERRIDE;
1434dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void EmitSwap(size_t index) OVERRIDE;
1444dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void SpillScratch(int reg) OVERRIDE;
1454dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void RestoreScratch(int reg) OVERRIDE;
1464dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1474dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Exchange(int index1, int index2, bool double_slot);
1484dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1494dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* GetAssembler() const;
1504dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1514dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
1524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64* const codegen_;
1534dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1544dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverMIPS64);
1554dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
1564dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1574dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass SlowPathCodeMIPS64 : public SlowPathCode {
1584dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
1594dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  SlowPathCodeMIPS64() : entry_label_(), exit_label_() {}
1604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
161a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* GetEntryLabel() { return &entry_label_; }
162a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* GetExitLabel() { return &exit_label_; }
1634dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
165a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label entry_label_;
166a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label exit_label_;
1674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(SlowPathCodeMIPS64);
1694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
1704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass LocationsBuilderMIPS64 : public HGraphVisitor {
1724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
1734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  LocationsBuilderMIPS64(HGraph* graph, CodeGeneratorMIPS64* codegen)
1744dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze      : HGraphVisitor(graph), codegen_(codegen) {}
1754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#define DECLARE_VISIT_INSTRUCTION(name, super)     \
177f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void Visit##name(H##name* instr) OVERRIDE;
1784dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
179f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
180f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(DECLARE_VISIT_INSTRUCTION)
1814dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1824dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#undef DECLARE_VISIT_INSTRUCTION
1834dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
184f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void VisitInstruction(HInstruction* instruction) OVERRIDE {
185f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames    LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
186f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames               << " (id " << instruction->GetId() << ")";
187f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  }
188f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames
1894dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
1904dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleInvoke(HInvoke* invoke);
1914dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleBinaryOp(HBinaryOperation* operation);
1924dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleShift(HBinaryOperation* operation);
1934dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
1944dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
1954dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1964dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InvokeDexCallingConventionVisitorMIPS64 parameter_visitor_;
1974dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
1984dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64* const codegen_;
1994dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2004dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(LocationsBuilderMIPS64);
2014dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
2024dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2034dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass InstructionCodeGeneratorMIPS64 : public HGraphVisitor {
2044dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
2054dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InstructionCodeGeneratorMIPS64(HGraph* graph, CodeGeneratorMIPS64* codegen);
2064dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2074dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#define DECLARE_VISIT_INSTRUCTION(name, super)     \
208f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void Visit##name(H##name* instr) OVERRIDE;
2094dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
210f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
211f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(DECLARE_VISIT_INSTRUCTION)
2124dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2134dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#undef DECLARE_VISIT_INSTRUCTION
2144dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
215f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  void VisitInstruction(HInstruction* instruction) OVERRIDE {
216f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames    LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
217f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames               << " (id " << instruction->GetId() << ")";
218f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames  }
219f39e0641a6d1a6561b20f6a130d1e763788cd70bAlexandre Rames
2204dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* GetAssembler() const { return assembler_; }
2214dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2224dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
2234dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateClassInitializationCheck(SlowPathCodeMIPS64* slow_path, GpuRegister class_reg);
2244dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateMemoryBarrier(MemBarrierKind kind);
2254dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
2264dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleBinaryOp(HBinaryOperation* operation);
2274dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleShift(HBinaryOperation* operation);
2284dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
2294dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
2304dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateImplicitNullCheck(HNullCheck* instruction);
2314dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateExplicitNullCheck(HNullCheck* instruction);
2324dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateTestAndBranch(HInstruction* instruction,
2330debae7bc89eb05f7a2bf7dccd223318fad7c88dDavid Brazdil                             size_t condition_input_index,
234a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze                             Mips64Label* true_target,
235a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze                             Mips64Label* false_target);
236c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void DivRemOneOrMinusOne(HBinaryOperation* instruction);
237c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void DivRemByPowerOfTwo(HBinaryOperation* instruction);
238c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
239c857c746707dfd45d74b75cb7fa84484ca68cc2aAlexey Frunze  void GenerateDivRemIntegral(HBinaryOperation* instruction);
240299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze  void GenerateIntLongCompare(IfCondition cond, bool is64bit, LocationSummary* locations);
241299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze  void GenerateIntLongCompareAndBranch(IfCondition cond,
242299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                       bool is64bit,
243299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                       LocationSummary* locations,
244299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                       Mips64Label* label);
245299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze  void GenerateFpCompareAndBranch(IfCondition cond,
246299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  bool gt_bias,
247299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  Primitive::Type type,
248299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  LocationSummary* locations,
249299a93993fb8f3efbf0465cf674d80c3bcfdc66cAlexey Frunze                                  Mips64Label* label);
250fc6a86ab2b70781e72b807c1798b83829ca7f931David Brazdil  void HandleGoto(HInstruction* got, HBasicBlock* successor);
2514dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* const assembler_;
2534dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64* const codegen_;
2544dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2554dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorMIPS64);
2564dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
2574dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2584dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunzeclass CodeGeneratorMIPS64 : public CodeGenerator {
2594dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze public:
2604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  CodeGeneratorMIPS64(HGraph* graph,
2614dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                      const Mips64InstructionSetFeatures& isa_features,
262ecc4366670e12b4812ef1653f7c8d52234ca1b1fSerban Constantinescu                      const CompilerOptions& compiler_options,
263ecc4366670e12b4812ef1653f7c8d52234ca1b1fSerban Constantinescu                      OptimizingCompilerStats* stats = nullptr);
2644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  virtual ~CodeGeneratorMIPS64() {}
2654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateFrameEntry() OVERRIDE;
2674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void GenerateFrameExit() OVERRIDE;
2684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Bind(HBasicBlock* block) OVERRIDE;
2704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE;
2724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t GetWordSize() const OVERRIDE { return kMips64WordSize; }
2744dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t GetFloatingPointSpillSlotSize() const OVERRIDE { return kMips64WordSize; }
2764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2774dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
278a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze    return assembler_.GetLabelLocation(GetLabelOf(block));
2794dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
2804dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2814dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; }
2824dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  HGraphVisitor* GetInstructionVisitor() OVERRIDE { return &instruction_visitor_; }
2834dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler* GetAssembler() OVERRIDE { return &assembler_; }
284eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  const Mips64Assembler& GetAssembler() const OVERRIDE { return assembler_; }
2854dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2864dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void MarkGCCard(GpuRegister object, GpuRegister value);
2874dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2884dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Register allocation.
2894dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2904dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void SetupBlockedRegisters(bool is_baseline) const OVERRIDE;
2914dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // AllocateFreeRegister() is only used when allocating registers locally
2924dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // during CompileBaseline().
2934dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE;
2944dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2954dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
2964dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
2974dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id);
2984dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id);
2994dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id);
3004dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id);
3014dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3024dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
3034dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
3044dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3054dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InstructionSet GetInstructionSet() const OVERRIDE { return InstructionSet::kMips64; }
3064dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3074dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  const Mips64InstructionSetFeatures& GetInstructionSetFeatures() const {
3084dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze    return isa_features_;
3094dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
3104dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
311a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* GetLabelOf(HBasicBlock* block) const {
312a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze    return CommonGetLabelOf<Mips64Label>(block_labels_, block);
3134dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
3144dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3154dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Initialize() OVERRIDE {
316a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze    block_labels_ = CommonInitializeLabels<Mips64Label>();
3174dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  }
3184dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3194dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void Finalize(CodeAllocator* allocator) OVERRIDE;
3204dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3214dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Code generation helpers.
322e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE;
3234dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
324175dc732c80e6f2afd83209348124df349290ba8Calin Juravle  void MoveConstant(Location destination, int32_t value) OVERRIDE;
325175dc732c80e6f2afd83209348124df349290ba8Calin Juravle
326e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle  void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE;
327e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
328e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle
3294dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void SwapLocations(Location loc1, Location loc2, Primitive::Type type);
3304dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3314dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Generate code to invoke a runtime entry point.
332175dc732c80e6f2afd83209348124df349290ba8Calin Juravle  void InvokeRuntime(QuickEntrypointEnum entrypoint,
333175dc732c80e6f2afd83209348124df349290ba8Calin Juravle                     HInstruction* instruction,
334175dc732c80e6f2afd83209348124df349290ba8Calin Juravle                     uint32_t dex_pc,
335175dc732c80e6f2afd83209348124df349290ba8Calin Juravle                     SlowPathCode* slow_path) OVERRIDE;
336175dc732c80e6f2afd83209348124df349290ba8Calin Juravle
3374dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  void InvokeRuntime(int32_t offset,
3384dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                     HInstruction* instruction,
3394dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                     uint32_t dex_pc,
3404dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze                     SlowPathCode* slow_path);
3414dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3424dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; }
3434dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3444dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const { return false; }
3454dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
346dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko  // Check if the desired_dispatch_info is supported. If it is, return it,
347dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko  // otherwise return a fall-back info that should be used instead.
348dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko  HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
349dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko      const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
350dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko      MethodReference target_method) OVERRIDE;
351dc151b2346bb8a4fdeed0c06e54c2fca21d59b5dVladimir Marko
35285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe  void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
35353afca191ace3d7447b09097f9ea82a513075c52Alexey Frunze  void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
35485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe
35585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe  void MoveFromReturnRegister(Location trg ATTRIBUTE_UNUSED,
35685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe                              Primitive::Type type ATTRIBUTE_UNUSED) OVERRIDE {
35785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe    UNIMPLEMENTED(FATAL);
35885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe  }
3594dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3604dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze private:
3614dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  // Labels for each block that will be compiled.
362a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label* block_labels_;  // Indexed by block id.
363a0e87b0a97fadd54540ec7e8331b61bebd82d378Alexey Frunze  Mips64Label frame_entry_label_;
3644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  LocationsBuilderMIPS64 location_builder_;
3654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  InstructionCodeGeneratorMIPS64 instruction_visitor_;
3664dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  ParallelMoveResolverMIPS64 move_resolver_;
3674dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  Mips64Assembler assembler_;
3684dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  const Mips64InstructionSetFeatures& isa_features_;
3694dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3704dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze  DISALLOW_COPY_AND_ASSIGN(CodeGeneratorMIPS64);
3714dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze};
3724dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3734dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze}  // namespace mips64
3744dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze}  // namespace art
3754dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze
3764dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_MIPS64_H_
377