code_generator_x86.h revision 0debae7bc89eb05f7a2bf7dccd223318fad7c88d
1734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller/* 2734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Copyright (C) 2014 The Android Open Source Project 3734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * 4734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Licensed under the Apache License, Version 2.0 (the "License"); 5734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * you may not use this file except in compliance with the License. 6734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * You may obtain a copy of the License at 7734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * 8734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * http://www.apache.org/licenses/LICENSE-2.0 9734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * 10734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Unless required by applicable law or agreed to in writing, software 11734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * distributed under the License is distributed on an "AS IS" BASIS, 12734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * See the License for the specific language governing permissions and 14734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * limitations under the License. 15734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller */ 16734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 17734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 18734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 19734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 20734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "code_generator.h" 21734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "dex/compiler_enums.h" 22734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "driver/compiler_options.h" 23734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "nodes.h" 24734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "parallel_move_resolver.h" 25734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include "utils/x86/assembler_x86.h" 26734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 27734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillernamespace art { 28734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillernamespace x86 { 29734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 30734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Use a local definition to prevent copying mistakes. 31734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kX86WordSize = kX86PointerSize; 32734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 33734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass CodeGeneratorX86; 34734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 35734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX }; 36734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX }; 37734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 38734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr XmmRegister kParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 }; 39734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters); 40734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 41734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX, EBX }; 42734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kRuntimeParameterCoreRegistersLength = 43734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller arraysize(kRuntimeParameterCoreRegisters); 44734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr XmmRegister kRuntimeParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 }; 45734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic constexpr size_t kRuntimeParameterFpuRegistersLength = 46734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller arraysize(kRuntimeParameterFpuRegisters); 47734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 48734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InvokeRuntimeCallingConvention : public CallingConvention<Register, XmmRegister> { 49734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 50734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InvokeRuntimeCallingConvention() 51734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller : CallingConvention(kRuntimeParameterCoreRegisters, 52734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kRuntimeParameterCoreRegistersLength, 53734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kRuntimeParameterFpuRegisters, 54734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kRuntimeParameterFpuRegistersLength, 55734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kX86PointerSize) {} 56734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 57734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 58734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); 59734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 60734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 61734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InvokeDexCallingConvention : public CallingConvention<Register, XmmRegister> { 62734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 63734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InvokeDexCallingConvention() : CallingConvention( 64734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kParameterCoreRegisters, 65734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kParameterCoreRegistersLength, 66734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kParameterFpuRegisters, 67734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kParameterFpuRegistersLength, 68734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller kX86PointerSize) {} 69734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 70734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller RegisterPair GetRegisterPairAt(size_t argument_index) { 71734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DCHECK_LT(argument_index + 1, GetNumberOfRegisters()); 72734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return kParameterCorePairRegisters[argument_index]; 73734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 74734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 75734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 76734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 77734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 78734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 79734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InvokeDexCallingConventionVisitorX86 : public InvokeDexCallingConventionVisitor { 80734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 81d1d16998adea189d5f24a774aa06e0e4e5f3e7ebAurimas Liutikas InvokeDexCallingConventionVisitorX86() {} 82d1d16998adea189d5f24a774aa06e0e4e5f3e7ebAurimas Liutikas virtual ~InvokeDexCallingConventionVisitorX86() {} 83734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 84734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetNextLocation(Primitive::Type type) OVERRIDE; 85734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetReturnLocation(Primitive::Type type) const OVERRIDE; 86734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetMethodLocation() const OVERRIDE; 87734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 88734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 89734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InvokeDexCallingConvention calling_convention; 90734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 91734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorX86); 92734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 93734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 94734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass FieldAccessCallingConventionX86 : public FieldAccessCallingConvention { 95734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 96734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller FieldAccessCallingConventionX86() {} 97734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 98734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetObjectLocation() const OVERRIDE { 99734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return Location::RegisterLocation(ECX); 100734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 101734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetFieldIndexLocation() const OVERRIDE { 102734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return Location::RegisterLocation(EAX); 103734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 104734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetReturnLocation(Primitive::Type type) const OVERRIDE { 105734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return Primitive::Is64BitType(type) 106734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ? Location::RegisterPairLocation(EAX, EDX) 107734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller : Location::RegisterLocation(EAX); 108734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 109734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { 110734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return Primitive::Is64BitType(type) 111734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ? Location::RegisterPairLocation(EDX, EBX) 112734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller : (is_instance 113734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ? Location::RegisterLocation(EDX) 114622cfadc8f0d294f875151fe1d8985e0553795eaMathias Agopian : Location::RegisterLocation(ECX)); 115734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 116734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { 117734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return Location::FpuRegisterLocation(XMM0); 118734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 119734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 120734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 121734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionX86); 122734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 123734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 124734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass ParallelMoveResolverX86 : public ParallelMoveResolverWithSwap { 125734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 126734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen) 127734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {} 128734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 129734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void EmitMove(size_t index) OVERRIDE; 130734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void EmitSwap(size_t index) OVERRIDE; 131734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void SpillScratch(int reg) OVERRIDE; 132734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void RestoreScratch(int reg) OVERRIDE; 133734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 134734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller X86Assembler* GetAssembler() const; 135734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 136734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 137734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Exchange(Register reg, int mem); 138734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Exchange(int mem1, int mem2); 139734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Exchange32(XmmRegister reg, int mem); 140734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MoveMemoryToMemory32(int dst, int src); 141734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MoveMemoryToMemory64(int dst, int src); 142734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 143734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller CodeGeneratorX86* const codegen_; 144734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 145734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86); 146734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 147734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 148734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass LocationsBuilderX86 : public HGraphVisitor { 149734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 150734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen) 151734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller : HGraphVisitor(graph), codegen_(codegen) {} 152734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 153734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define DECLARE_VISIT_INSTRUCTION(name, super) \ 154734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Visit##name(H##name* instr) OVERRIDE; 155734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 156734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) 157734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION) 158734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 159734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#undef DECLARE_VISIT_INSTRUCTION 160734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 161734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void VisitInstruction(HInstruction* instruction) OVERRIDE { 162734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() 163734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller << " (id " << instruction->GetId() << ")"; 164734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 165734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 166734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 167734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleBitwiseOperation(HBinaryOperation* instruction); 168734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleInvoke(HInvoke* invoke); 169734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleShift(HBinaryOperation* instruction); 170734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info); 171734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); 172734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 173734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller CodeGeneratorX86* const codegen_; 174734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InvokeDexCallingConventionVisitorX86 parameter_visitor_; 175734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 176734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86); 177734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 178734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 179734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass InstructionCodeGeneratorX86 : public HGraphVisitor { 180734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 181734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen); 182734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 183734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define DECLARE_VISIT_INSTRUCTION(name, super) \ 184734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Visit##name(H##name* instr) OVERRIDE; 185734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 186734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) 187734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION) 188734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 189734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#undef DECLARE_VISIT_INSTRUCTION 190734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 191734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void VisitInstruction(HInstruction* instruction) OVERRIDE { 192734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() 193734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller << " (id " << instruction->GetId() << ")"; 194734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 1955880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall 196734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller X86Assembler* GetAssembler() const { return assembler_; } 197734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 198734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 199734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Generate code for the given suspend check. If not null, `successor` 200734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // is the block to branch to if the suspend check is not needed, and after 201734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // the suspend call. 202734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor); 203734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateClassInitializationCheck(SlowPathCode* slow_path, Register class_reg); 204734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleBitwiseOperation(HBinaryOperation* instruction); 205734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateDivRemIntegral(HBinaryOperation* instruction); 206734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void DivRemOneOrMinusOne(HBinaryOperation* instruction); 207734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void DivByPowerOfTwo(HDiv* instruction); 208734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); 209734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateRemFP(HRem* rem); 210734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleShift(HBinaryOperation* instruction); 211734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateShlLong(const Location& loc, Register shifter); 212734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateShrLong(const Location& loc, Register shifter); 213734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateUShrLong(const Location& loc, Register shifter); 214734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateShlLong(const Location& loc, int shift); 215734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateShrLong(const Location& loc, int shift); 216734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateUShrLong(const Location& loc, int shift); 217734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateMemoryBarrier(MemBarrierKind kind); 218734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleFieldSet(HInstruction* instruction, 219734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const FieldInfo& field_info, 220734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller bool value_can_be_null); 221734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); 222734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Push value to FPU stack. `is_fp` specifies whether the value is floating point or not. 223734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // `is_wide` specifies whether it is long/double or not. 224734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void PushOntoFPStack(Location source, uint32_t temp_offset, 225734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uint32_t stack_adjustment, bool is_fp, bool is_wide); 226734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 227734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateImplicitNullCheck(HNullCheck* instruction); 228734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateExplicitNullCheck(HNullCheck* instruction); 229734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateTestAndBranch(HInstruction* instruction, 230734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t condition_input_index, 231734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* true_target, 232734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* false_target); 233734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateCompareTestAndBranch(HCondition* condition, 234734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* true_target, 235734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* false_target); 236734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateFPJumps(HCondition* cond, Label* true_label, Label* false_label); 237734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateLongComparesAndJumps(HCondition* cond, Label* true_label, Label* false_label); 238734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void HandleGoto(HInstruction* got, HBasicBlock* successor); 239734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 240734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller X86Assembler* const assembler_; 241734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller CodeGeneratorX86* const codegen_; 242734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 243734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86); 244734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 245734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 246734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass JumpTableRIPFixup; 247734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 248734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass CodeGeneratorX86 : public CodeGenerator { 249734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller public: 250734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller CodeGeneratorX86(HGraph* graph, 251734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const X86InstructionSetFeatures& isa_features, 252734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const CompilerOptions& compiler_options, 253734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller OptimizingCompilerStats* stats = nullptr); 254734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller virtual ~CodeGeneratorX86() {} 255734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 256734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateFrameEntry() OVERRIDE; 257734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateFrameExit() OVERRIDE; 258734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Bind(HBasicBlock* block) OVERRIDE; 259734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Move(HInstruction* instruction, Location location, HInstruction* move_for) OVERRIDE; 260734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MoveConstant(Location destination, int32_t value) OVERRIDE; 261734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE; 262734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE; 263734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 264734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 265734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 266734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 267734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE; 268734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 269734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Generate code to invoke a runtime entry point. 270734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void InvokeRuntime(QuickEntrypointEnum entrypoint, 271734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller HInstruction* instruction, 272734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uint32_t dex_pc, 273734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller SlowPathCode* slow_path) OVERRIDE; 274734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 275734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void InvokeRuntime(int32_t entry_point_offset, 276734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller HInstruction* instruction, 277734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uint32_t dex_pc, 278734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller SlowPathCode* slow_path); 279734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 280734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t GetWordSize() const OVERRIDE { 281734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return kX86WordSize; 282734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 283734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 284734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller size_t GetFloatingPointSpillSlotSize() const OVERRIDE { 285734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 8 bytes == 2 words for each spill. 286734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return 2 * kX86WordSize; 287734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 288734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 289734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller HGraphVisitor* GetLocationBuilder() OVERRIDE { 290734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return &location_builder_; 291734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 292734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 293734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller HGraphVisitor* GetInstructionVisitor() OVERRIDE { 294734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return &instruction_visitor_; 295734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 296734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 297734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller X86Assembler* GetAssembler() OVERRIDE { 298734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return &assembler_; 299734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 300734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 301734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const X86Assembler& GetAssembler() const OVERRIDE { 302734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return assembler_; 303734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 304734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 305734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE { 306734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return GetLabelOf(block)->Position(); 307734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 308734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 309734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void SetupBlockedRegisters(bool is_baseline) const OVERRIDE; 310734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 311734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE; 312734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 313734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location GetStackLocation(HLoadLocal* load) const OVERRIDE; 314734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 315734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE; 316734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE; 317734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 318734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Blocks all register pairs made out of blocked core registers. 319734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void UpdateBlockedPairRegisters() const; 320734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 321734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ParallelMoveResolverX86* GetMoveResolver() OVERRIDE { 322734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return &move_resolver_; 323734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 324734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 325734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InstructionSet GetInstructionSet() const OVERRIDE { 326734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return InstructionSet::kX86; 327734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 328734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 329734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Helper method to move a 32bits value between two locations. 330734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Move32(Location destination, Location source); 331734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Helper method to move a 64bits value between two locations. 332734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Move64(Location destination, Location source); 333734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 334734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Check if the desired_dispatch_info is supported. If it is, return it, 335734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // otherwise return a fall-back info that should be used instead. 336734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch( 337734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info, 338734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller MethodReference target_method) OVERRIDE; 339734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 340734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Generate a call to a static or direct method. 341734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE; 342734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Generate a call to a virtual method. 343734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE; 344734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 345734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MoveFromReturnRegister(Location trg, Primitive::Type type) OVERRIDE; 346734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 347734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Emit linker patches. 348734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patches) OVERRIDE; 349734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 350734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Emit a write barrier. 351734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MarkGCCard(Register temp, 352734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Register card, 353734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Register object, 354734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Register value, 355734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller bool value_can_be_null); 356734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 357734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* GetLabelOf(HBasicBlock* block) const { 358734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return CommonGetLabelOf<Label>(block_labels_, block); 359734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 360734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 361734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Initialize() OVERRIDE { 362734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller block_labels_ = CommonInitializeLabels<Label>(); 363734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 364734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 365734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller bool NeedsTwoRegisters(Primitive::Type type) const OVERRIDE { 366734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return type == Primitive::kPrimLong; 367734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 368734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 369734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller bool ShouldSplitLongMoves() const OVERRIDE { return true; } 370734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 371734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* GetFrameEntryLabel() { return &frame_entry_label_; } 372734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 373734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const X86InstructionSetFeatures& GetInstructionSetFeatures() const { 374734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return isa_features_; 375734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 376734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 377734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void SetMethodAddressOffset(int32_t offset) { 378734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller method_address_offset_ = offset; 379734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 380734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 381734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller int32_t GetMethodAddressOffset() const { 382734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return method_address_offset_; 383734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 384734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 385734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller int32_t ConstantAreaStart() const { 386734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller return constant_area_start_; 387734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller } 388734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 389734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Address LiteralDoubleAddress(double v, Register reg); 390734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Address LiteralFloatAddress(float v, Register reg); 391734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Address LiteralInt32Address(int32_t v, Register reg); 392734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Address LiteralInt64Address(int64_t v, Register reg); 393734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 394734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Address LiteralCaseTable(HX86PackedSwitch* switch_instr, Register reg, Register value); 395734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 396734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void Finalize(CodeAllocator* allocator) OVERRIDE; 397734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 398734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Generate a read barrier for a heap reference within `instruction`. 399734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 400734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // A read barrier for an object reference read from the heap is 401734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // implemented as a call to the artReadBarrierSlow runtime entry 402734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // point, which is passed the values in locations `ref`, `obj`, and 403734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // `offset`: 404734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 405734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // mirror::Object* artReadBarrierSlow(mirror::Object* ref, 406734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // mirror::Object* obj, 407734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // uint32_t offset); 408734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 409734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // The `out` location contains the value returned by 410734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // artReadBarrierSlow. 411734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 412b685c542836b93c99cd85053e07696406ea37adbJesse Hall // When `index` is provided (i.e. for array accesses), the offset 413734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // value passed to artReadBarrierSlow is adjusted to take `index` 414734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // into account. 415734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateReadBarrier(HInstruction* instruction, 416734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location out, 417734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location ref, 418734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location obj, 419734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uint32_t offset, 420734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location index = Location::NoLocation()); 421734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 422734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // If read barriers are enabled, generate a read barrier for a heap reference. 423734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // If heap poisoning is enabled, also unpoison the reference in `out`. 424734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void MaybeGenerateReadBarrier(HInstruction* instruction, 425734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location out, 426734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location ref, 427734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location obj, 428734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uint32_t offset, 429734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Location index = Location::NoLocation()); 430734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 4315880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall // Generate a read barrier for a GC root within `instruction`. 432734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 433734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // A read barrier for an object reference GC root is implemented as 434734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // a call to the artReadBarrierForRootSlow runtime entry point, 435734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // which is passed the value in location `root`: 436734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 437734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root); 438734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // 439734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // The `out` location contains the value returned by 440734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // artReadBarrierForRootSlow. 441734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller void GenerateReadBarrierForRoot(HInstruction* instruction, Location out, Location root); 442734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 443734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller private: 444734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp); 445734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 446734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller struct PcRelativeDexCacheAccessInfo { 447734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller PcRelativeDexCacheAccessInfo(const DexFile& dex_file, uint32_t element_off) 448734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller : target_dex_file(dex_file), element_offset(element_off), label() { } 449734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 450734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const DexFile& target_dex_file; 451734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller uint32_t element_offset; 452734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // NOTE: Label is bound to the end of the instruction that has an embedded 32-bit offset. 453734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label label; 454734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller }; 455734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 456734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Labels for each block that will be compiled. 457734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label* block_labels_; // Indexed by block id. 458734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller Label frame_entry_label_; 459734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller LocationsBuilderX86 location_builder_; 460734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller InstructionCodeGeneratorX86 instruction_visitor_; 461734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ParallelMoveResolverX86 move_resolver_; 462734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller X86Assembler assembler_; 463734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller const X86InstructionSetFeatures& isa_features_; 464734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 465734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Method patch info. Using ArenaDeque<> which retains element addresses on push/emplace_back(). 466734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ArenaDeque<MethodPatchInfo<Label>> method_patches_; 467734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ArenaDeque<MethodPatchInfo<Label>> relative_call_patches_; 468734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // PC-relative DexCache access info. 469734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ArenaDeque<PcRelativeDexCacheAccessInfo> pc_relative_dex_cache_patches_; 470734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 471734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Offset to the start of the constant area in the assembled code. 472734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Used for fixups to the constant area. 473734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller int32_t constant_area_start_; 474734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 475734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // Fixups for jump tables that need to be patched after the constant table is generated. 476734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller ArenaVector<JumpTableRIPFixup*> fixups_to_jump_tables_; 477734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 478734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // If there is a HX86ComputeBaseMethodAddress instruction in the graph 479734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // (which shall be the sole instruction of this kind), subtracting this offset 480734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // from the value contained in the out register of this HX86ComputeBaseMethodAddress 481b685c542836b93c99cd85053e07696406ea37adbJesse Hall // instruction gives the address of the start of this method. 482734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller int32_t method_address_offset_; 483734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 484734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // When we don't know the proper offset for the value, we use kDummy32BitOffset. 485734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller // The correct value will be inserted when processing Assembler fixups. 486734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller static constexpr int32_t kDummy32BitOffset = 256; 487734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 488734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86); 489734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}; 490734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 491734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller} // namespace x86 492734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller} // namespace art 493734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller 494b685c542836b93c99cd85053e07696406ea37adbJesse Hall#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 495b685c542836b93c99cd85053e07696406ea37adbJesse Hall