1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "arch/x86/instruction_set_features_x86.h" 21*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h" 23*795d594fSAndroid Build Coastguard Worker #include "code_generator.h" 24*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h" 25*795d594fSAndroid Build Coastguard Worker #include "driver/compiler_options.h" 26*795d594fSAndroid Build Coastguard Worker #include "nodes.h" 27*795d594fSAndroid Build Coastguard Worker #include "parallel_move_resolver.h" 28*795d594fSAndroid Build Coastguard Worker #include "utils/x86/assembler_x86.h" 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 31*795d594fSAndroid Build Coastguard Worker namespace x86 { 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker // Use a local definition to prevent copying mistakes. 34*795d594fSAndroid Build Coastguard Worker static constexpr size_t kX86WordSize = static_cast<size_t>(kX86PointerSize); 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker class CodeGeneratorX86; 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX }; 39*795d594fSAndroid Build Coastguard Worker static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX }; 40*795d594fSAndroid Build Coastguard Worker static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 41*795d594fSAndroid Build Coastguard Worker static constexpr XmmRegister kParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 }; 42*795d594fSAndroid Build Coastguard Worker static constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters); 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX, EBX }; 45*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRuntimeParameterCoreRegistersLength = 46*795d594fSAndroid Build Coastguard Worker arraysize(kRuntimeParameterCoreRegisters); 47*795d594fSAndroid Build Coastguard Worker static constexpr XmmRegister kRuntimeParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 }; 48*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRuntimeParameterFpuRegistersLength = 49*795d594fSAndroid Build Coastguard Worker arraysize(kRuntimeParameterFpuRegisters); 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker #define UNIMPLEMENTED_INTRINSIC_LIST_X86(V) \ 52*795d594fSAndroid Build Coastguard Worker V(MathSignumFloat) \ 53*795d594fSAndroid Build Coastguard Worker V(MathSignumDouble) \ 54*795d594fSAndroid Build Coastguard Worker V(MathCopySignFloat) \ 55*795d594fSAndroid Build Coastguard Worker V(MathCopySignDouble) \ 56*795d594fSAndroid Build Coastguard Worker V(MathRoundDouble) \ 57*795d594fSAndroid Build Coastguard Worker V(FloatIsInfinite) \ 58*795d594fSAndroid Build Coastguard Worker V(DoubleIsInfinite) \ 59*795d594fSAndroid Build Coastguard Worker V(IntegerHighestOneBit) \ 60*795d594fSAndroid Build Coastguard Worker V(LongHighestOneBit) \ 61*795d594fSAndroid Build Coastguard Worker V(LongDivideUnsigned) \ 62*795d594fSAndroid Build Coastguard Worker V(IntegerRemainderUnsigned) \ 63*795d594fSAndroid Build Coastguard Worker V(LongRemainderUnsigned) \ 64*795d594fSAndroid Build Coastguard Worker V(CRC32Update) \ 65*795d594fSAndroid Build Coastguard Worker V(CRC32UpdateBytes) \ 66*795d594fSAndroid Build Coastguard Worker V(CRC32UpdateByteBuffer) \ 67*795d594fSAndroid Build Coastguard Worker V(FP16ToFloat) \ 68*795d594fSAndroid Build Coastguard Worker V(FP16ToHalf) \ 69*795d594fSAndroid Build Coastguard Worker V(FP16Floor) \ 70*795d594fSAndroid Build Coastguard Worker V(FP16Ceil) \ 71*795d594fSAndroid Build Coastguard Worker V(FP16Rint) \ 72*795d594fSAndroid Build Coastguard Worker V(FP16Greater) \ 73*795d594fSAndroid Build Coastguard Worker V(FP16GreaterEquals) \ 74*795d594fSAndroid Build Coastguard Worker V(FP16Less) \ 75*795d594fSAndroid Build Coastguard Worker V(FP16LessEquals) \ 76*795d594fSAndroid Build Coastguard Worker V(FP16Compare) \ 77*795d594fSAndroid Build Coastguard Worker V(FP16Min) \ 78*795d594fSAndroid Build Coastguard Worker V(FP16Max) \ 79*795d594fSAndroid Build Coastguard Worker V(MathMultiplyHigh) \ 80*795d594fSAndroid Build Coastguard Worker V(StringStringIndexOf) \ 81*795d594fSAndroid Build Coastguard Worker V(StringStringIndexOfAfter) \ 82*795d594fSAndroid Build Coastguard Worker V(StringBufferAppend) \ 83*795d594fSAndroid Build Coastguard Worker V(StringBufferLength) \ 84*795d594fSAndroid Build Coastguard Worker V(StringBufferToString) \ 85*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendObject) \ 86*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendString) \ 87*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendCharSequence) \ 88*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendCharArray) \ 89*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendBoolean) \ 90*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendChar) \ 91*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendInt) \ 92*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendLong) \ 93*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendFloat) \ 94*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendDouble) \ 95*795d594fSAndroid Build Coastguard Worker V(StringBuilderLength) \ 96*795d594fSAndroid Build Coastguard Worker V(StringBuilderToString) \ 97*795d594fSAndroid Build Coastguard Worker V(UnsafeArrayBaseOffset) \ 98*795d594fSAndroid Build Coastguard Worker /* 1.8 */ \ 99*795d594fSAndroid Build Coastguard Worker V(MethodHandleInvokeExact) \ 100*795d594fSAndroid Build Coastguard Worker V(MethodHandleInvoke) \ 101*795d594fSAndroid Build Coastguard Worker /* OpenJDK 11 */ \ 102*795d594fSAndroid Build Coastguard Worker V(JdkUnsafeArrayBaseOffset) 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker class InvokeRuntimeCallingConvention : public CallingConvention<Register, XmmRegister> { 105*795d594fSAndroid Build Coastguard Worker public: InvokeRuntimeCallingConvention()106*795d594fSAndroid Build Coastguard Worker InvokeRuntimeCallingConvention() 107*795d594fSAndroid Build Coastguard Worker : CallingConvention(kRuntimeParameterCoreRegisters, 108*795d594fSAndroid Build Coastguard Worker kRuntimeParameterCoreRegistersLength, 109*795d594fSAndroid Build Coastguard Worker kRuntimeParameterFpuRegisters, 110*795d594fSAndroid Build Coastguard Worker kRuntimeParameterFpuRegistersLength, 111*795d594fSAndroid Build Coastguard Worker kX86PointerSize) {} 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker private: 114*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); 115*795d594fSAndroid Build Coastguard Worker }; 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker class InvokeDexCallingConvention : public CallingConvention<Register, XmmRegister> { 118*795d594fSAndroid Build Coastguard Worker public: InvokeDexCallingConvention()119*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConvention() : CallingConvention( 120*795d594fSAndroid Build Coastguard Worker kParameterCoreRegisters, 121*795d594fSAndroid Build Coastguard Worker kParameterCoreRegistersLength, 122*795d594fSAndroid Build Coastguard Worker kParameterFpuRegisters, 123*795d594fSAndroid Build Coastguard Worker kParameterFpuRegistersLength, 124*795d594fSAndroid Build Coastguard Worker kX86PointerSize) {} 125*795d594fSAndroid Build Coastguard Worker GetRegisterPairAt(size_t argument_index)126*795d594fSAndroid Build Coastguard Worker RegisterPair GetRegisterPairAt(size_t argument_index) { 127*795d594fSAndroid Build Coastguard Worker DCHECK_LT(argument_index + 1, GetNumberOfRegisters()); 128*795d594fSAndroid Build Coastguard Worker return kParameterCorePairRegisters[argument_index]; 129*795d594fSAndroid Build Coastguard Worker } 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker private: 132*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 133*795d594fSAndroid Build Coastguard Worker }; 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker class InvokeDexCallingConventionVisitorX86 : public InvokeDexCallingConventionVisitor { 136*795d594fSAndroid Build Coastguard Worker public: InvokeDexCallingConventionVisitorX86()137*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConventionVisitorX86() {} ~InvokeDexCallingConventionVisitorX86()138*795d594fSAndroid Build Coastguard Worker virtual ~InvokeDexCallingConventionVisitorX86() {} 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker Location GetNextLocation(DataType::Type type) override; 141*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type type) const override; 142*795d594fSAndroid Build Coastguard Worker Location GetMethodLocation() const override; 143*795d594fSAndroid Build Coastguard Worker 144*795d594fSAndroid Build Coastguard Worker private: 145*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConvention calling_convention; 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorX86); 148*795d594fSAndroid Build Coastguard Worker }; 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker class CriticalNativeCallingConventionVisitorX86 : public InvokeDexCallingConventionVisitor { 151*795d594fSAndroid Build Coastguard Worker public: CriticalNativeCallingConventionVisitorX86(bool for_register_allocation)152*795d594fSAndroid Build Coastguard Worker explicit CriticalNativeCallingConventionVisitorX86(bool for_register_allocation) 153*795d594fSAndroid Build Coastguard Worker : for_register_allocation_(for_register_allocation) {} 154*795d594fSAndroid Build Coastguard Worker ~CriticalNativeCallingConventionVisitorX86()155*795d594fSAndroid Build Coastguard Worker virtual ~CriticalNativeCallingConventionVisitorX86() {} 156*795d594fSAndroid Build Coastguard Worker 157*795d594fSAndroid Build Coastguard Worker Location GetNextLocation(DataType::Type type) override; 158*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type type) const override; 159*795d594fSAndroid Build Coastguard Worker Location GetMethodLocation() const override; 160*795d594fSAndroid Build Coastguard Worker GetStackOffset()161*795d594fSAndroid Build Coastguard Worker size_t GetStackOffset() const { return stack_offset_; } 162*795d594fSAndroid Build Coastguard Worker 163*795d594fSAndroid Build Coastguard Worker private: 164*795d594fSAndroid Build Coastguard Worker // Register allocator does not support adjusting frame size, so we cannot provide final locations 165*795d594fSAndroid Build Coastguard Worker // of stack arguments for register allocation. We ask the register allocator for any location and 166*795d594fSAndroid Build Coastguard Worker // move these arguments to the right place after adjusting the SP when generating the call. 167*795d594fSAndroid Build Coastguard Worker const bool for_register_allocation_; 168*795d594fSAndroid Build Coastguard Worker size_t stack_offset_ = 0u; 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(CriticalNativeCallingConventionVisitorX86); 171*795d594fSAndroid Build Coastguard Worker }; 172*795d594fSAndroid Build Coastguard Worker 173*795d594fSAndroid Build Coastguard Worker class FieldAccessCallingConventionX86 : public FieldAccessCallingConvention { 174*795d594fSAndroid Build Coastguard Worker public: FieldAccessCallingConventionX86()175*795d594fSAndroid Build Coastguard Worker FieldAccessCallingConventionX86() {} 176*795d594fSAndroid Build Coastguard Worker GetObjectLocation()177*795d594fSAndroid Build Coastguard Worker Location GetObjectLocation() const override { 178*795d594fSAndroid Build Coastguard Worker return Location::RegisterLocation(ECX); 179*795d594fSAndroid Build Coastguard Worker } GetFieldIndexLocation()180*795d594fSAndroid Build Coastguard Worker Location GetFieldIndexLocation() const override { 181*795d594fSAndroid Build Coastguard Worker return Location::RegisterLocation(EAX); 182*795d594fSAndroid Build Coastguard Worker } GetReturnLocation(DataType::Type type)183*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type type) const override { 184*795d594fSAndroid Build Coastguard Worker return DataType::Is64BitType(type) 185*795d594fSAndroid Build Coastguard Worker ? Location::RegisterPairLocation(EAX, EDX) 186*795d594fSAndroid Build Coastguard Worker : Location::RegisterLocation(EAX); 187*795d594fSAndroid Build Coastguard Worker } GetSetValueLocation(DataType::Type type,bool is_instance)188*795d594fSAndroid Build Coastguard Worker Location GetSetValueLocation(DataType::Type type, bool is_instance) const override { 189*795d594fSAndroid Build Coastguard Worker return DataType::Is64BitType(type) 190*795d594fSAndroid Build Coastguard Worker ? (is_instance 191*795d594fSAndroid Build Coastguard Worker ? Location::RegisterPairLocation(EDX, EBX) 192*795d594fSAndroid Build Coastguard Worker : Location::RegisterPairLocation(ECX, EDX)) 193*795d594fSAndroid Build Coastguard Worker : (is_instance 194*795d594fSAndroid Build Coastguard Worker ? Location::RegisterLocation(EDX) 195*795d594fSAndroid Build Coastguard Worker : Location::RegisterLocation(ECX)); 196*795d594fSAndroid Build Coastguard Worker } GetFpuLocation(DataType::Type type)197*795d594fSAndroid Build Coastguard Worker Location GetFpuLocation([[maybe_unused]] DataType::Type type) const override { 198*795d594fSAndroid Build Coastguard Worker return Location::FpuRegisterLocation(XMM0); 199*795d594fSAndroid Build Coastguard Worker } 200*795d594fSAndroid Build Coastguard Worker 201*795d594fSAndroid Build Coastguard Worker private: 202*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionX86); 203*795d594fSAndroid Build Coastguard Worker }; 204*795d594fSAndroid Build Coastguard Worker 205*795d594fSAndroid Build Coastguard Worker class ParallelMoveResolverX86 : public ParallelMoveResolverWithSwap { 206*795d594fSAndroid Build Coastguard Worker public: ParallelMoveResolverX86(ArenaAllocator * allocator,CodeGeneratorX86 * codegen)207*795d594fSAndroid Build Coastguard Worker ParallelMoveResolverX86(ArenaAllocator* allocator, CodeGeneratorX86* codegen) 208*795d594fSAndroid Build Coastguard Worker : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {} 209*795d594fSAndroid Build Coastguard Worker 210*795d594fSAndroid Build Coastguard Worker void EmitMove(size_t index) override; 211*795d594fSAndroid Build Coastguard Worker void EmitSwap(size_t index) override; 212*795d594fSAndroid Build Coastguard Worker void SpillScratch(int reg) override; 213*795d594fSAndroid Build Coastguard Worker void RestoreScratch(int reg) override; 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker X86Assembler* GetAssembler() const; 216*795d594fSAndroid Build Coastguard Worker 217*795d594fSAndroid Build Coastguard Worker private: 218*795d594fSAndroid Build Coastguard Worker void Exchange(Register reg, int mem); 219*795d594fSAndroid Build Coastguard Worker void Exchange32(XmmRegister reg, int mem); 220*795d594fSAndroid Build Coastguard Worker void Exchange128(XmmRegister reg, int mem); 221*795d594fSAndroid Build Coastguard Worker void ExchangeMemory(int mem1, int mem2, int number_of_words); 222*795d594fSAndroid Build Coastguard Worker void MoveMemoryToMemory(int dst, int src, int number_of_words); 223*795d594fSAndroid Build Coastguard Worker 224*795d594fSAndroid Build Coastguard Worker CodeGeneratorX86* const codegen_; 225*795d594fSAndroid Build Coastguard Worker 226*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverX86); 227*795d594fSAndroid Build Coastguard Worker }; 228*795d594fSAndroid Build Coastguard Worker 229*795d594fSAndroid Build Coastguard Worker class LocationsBuilderX86 : public HGraphVisitor { 230*795d594fSAndroid Build Coastguard Worker public: LocationsBuilderX86(HGraph * graph,CodeGeneratorX86 * codegen)231*795d594fSAndroid Build Coastguard Worker LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen) 232*795d594fSAndroid Build Coastguard Worker : HGraphVisitor(graph), codegen_(codegen) {} 233*795d594fSAndroid Build Coastguard Worker 234*795d594fSAndroid Build Coastguard Worker #define DECLARE_VISIT_INSTRUCTION(name, super) \ 235*795d594fSAndroid Build Coastguard Worker void Visit##name(H##name* instr) override; 236*795d594fSAndroid Build Coastguard Worker 237*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)238*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION) 239*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(DECLARE_VISIT_INSTRUCTION) 240*795d594fSAndroid Build Coastguard Worker 241*795d594fSAndroid Build Coastguard Worker #undef DECLARE_VISIT_INSTRUCTION 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker void VisitInstruction(HInstruction* instruction) override { 244*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() 245*795d594fSAndroid Build Coastguard Worker << " (id " << instruction->GetId() << ")"; 246*795d594fSAndroid Build Coastguard Worker } 247*795d594fSAndroid Build Coastguard Worker 248*795d594fSAndroid Build Coastguard Worker private: 249*795d594fSAndroid Build Coastguard Worker void HandleBitwiseOperation(HBinaryOperation* instruction); 250*795d594fSAndroid Build Coastguard Worker void HandleInvoke(HInvoke* invoke); 251*795d594fSAndroid Build Coastguard Worker void HandleCondition(HCondition* condition); 252*795d594fSAndroid Build Coastguard Worker void HandleRotate(HBinaryOperation* rotate); 253*795d594fSAndroid Build Coastguard Worker void HandleShift(HBinaryOperation* instruction); 254*795d594fSAndroid Build Coastguard Worker void HandleFieldSet(HInstruction* instruction, 255*795d594fSAndroid Build Coastguard Worker const FieldInfo& field_info, 256*795d594fSAndroid Build Coastguard Worker WriteBarrierKind write_barrier_kind); 257*795d594fSAndroid Build Coastguard Worker void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); 258*795d594fSAndroid Build Coastguard Worker bool CpuHasAvxFeatureFlag(); 259*795d594fSAndroid Build Coastguard Worker bool CpuHasAvx2FeatureFlag(); 260*795d594fSAndroid Build Coastguard Worker 261*795d594fSAndroid Build Coastguard Worker CodeGeneratorX86* const codegen_; 262*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConventionVisitorX86 parameter_visitor_; 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86); 265*795d594fSAndroid Build Coastguard Worker }; 266*795d594fSAndroid Build Coastguard Worker 267*795d594fSAndroid Build Coastguard Worker class InstructionCodeGeneratorX86 : public InstructionCodeGenerator { 268*795d594fSAndroid Build Coastguard Worker public: 269*795d594fSAndroid Build Coastguard Worker InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen); 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker #define DECLARE_VISIT_INSTRUCTION(name, super) \ 272*795d594fSAndroid Build Coastguard Worker void Visit##name(H##name* instr) override; 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION)275*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_X86(DECLARE_VISIT_INSTRUCTION) 276*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(DECLARE_VISIT_INSTRUCTION) 277*795d594fSAndroid Build Coastguard Worker 278*795d594fSAndroid Build Coastguard Worker #undef DECLARE_VISIT_INSTRUCTION 279*795d594fSAndroid Build Coastguard Worker 280*795d594fSAndroid Build Coastguard Worker void VisitInstruction(HInstruction* instruction) override { 281*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() 282*795d594fSAndroid Build Coastguard Worker << " (id " << instruction->GetId() << ")"; 283*795d594fSAndroid Build Coastguard Worker } 284*795d594fSAndroid Build Coastguard Worker GetAssembler()285*795d594fSAndroid Build Coastguard Worker X86Assembler* GetAssembler() const { return assembler_; } 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker // The compare/jump sequence will generate about (1.5 * num_entries) instructions. A jump 288*795d594fSAndroid Build Coastguard Worker // table version generates 7 instructions and num_entries literals. Compare/jump sequence will 289*795d594fSAndroid Build Coastguard Worker // generates less code/data with a small num_entries. 290*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kPackedSwitchJumpTableThreshold = 5; 291*795d594fSAndroid Build Coastguard Worker 292*795d594fSAndroid Build Coastguard Worker // Generate a GC root reference load: 293*795d594fSAndroid Build Coastguard Worker // 294*795d594fSAndroid Build Coastguard Worker // root <- *address 295*795d594fSAndroid Build Coastguard Worker // 296*795d594fSAndroid Build Coastguard Worker // while honoring read barriers based on read_barrier_option. 297*795d594fSAndroid Build Coastguard Worker void GenerateGcRootFieldLoad(HInstruction* instruction, 298*795d594fSAndroid Build Coastguard Worker Location root, 299*795d594fSAndroid Build Coastguard Worker const Address& address, 300*795d594fSAndroid Build Coastguard Worker Label* fixup_label, 301*795d594fSAndroid Build Coastguard Worker ReadBarrierOption read_barrier_option); 302*795d594fSAndroid Build Coastguard Worker 303*795d594fSAndroid Build Coastguard Worker void HandleFieldSet(HInstruction* instruction, 304*795d594fSAndroid Build Coastguard Worker uint32_t value_index, 305*795d594fSAndroid Build Coastguard Worker DataType::Type type, 306*795d594fSAndroid Build Coastguard Worker Address field_addr, 307*795d594fSAndroid Build Coastguard Worker Register base, 308*795d594fSAndroid Build Coastguard Worker bool is_volatile, 309*795d594fSAndroid Build Coastguard Worker bool value_can_be_null, 310*795d594fSAndroid Build Coastguard Worker WriteBarrierKind write_barrier_kind); 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker private: 313*795d594fSAndroid Build Coastguard Worker // Generate code for the given suspend check. If not null, `successor` 314*795d594fSAndroid Build Coastguard Worker // is the block to branch to if the suspend check is not needed, and after 315*795d594fSAndroid Build Coastguard Worker // the suspend call. 316*795d594fSAndroid Build Coastguard Worker void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor); 317*795d594fSAndroid Build Coastguard Worker void GenerateClassInitializationCheck(SlowPathCode* slow_path, Register class_reg); 318*795d594fSAndroid Build Coastguard Worker void GenerateBitstringTypeCheckCompare(HTypeCheckInstruction* check, Register temp); 319*795d594fSAndroid Build Coastguard Worker void HandleBitwiseOperation(HBinaryOperation* instruction); 320*795d594fSAndroid Build Coastguard Worker void GenerateDivRemIntegral(HBinaryOperation* instruction); 321*795d594fSAndroid Build Coastguard Worker void DivRemOneOrMinusOne(HBinaryOperation* instruction); 322*795d594fSAndroid Build Coastguard Worker void DivByPowerOfTwo(HDiv* instruction); 323*795d594fSAndroid Build Coastguard Worker void RemByPowerOfTwo(HRem* instruction); 324*795d594fSAndroid Build Coastguard Worker void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); 325*795d594fSAndroid Build Coastguard Worker void GenerateRemFP(HRem* rem); 326*795d594fSAndroid Build Coastguard Worker void HandleCondition(HCondition* condition); 327*795d594fSAndroid Build Coastguard Worker void HandleShift(HBinaryOperation* instruction); 328*795d594fSAndroid Build Coastguard Worker void GenerateShlLong(const Location& loc, Register shifter); 329*795d594fSAndroid Build Coastguard Worker void GenerateShrLong(const Location& loc, Register shifter); 330*795d594fSAndroid Build Coastguard Worker void GenerateUShrLong(const Location& loc, Register shifter); 331*795d594fSAndroid Build Coastguard Worker void GenerateShlLong(const Location& loc, int shift); 332*795d594fSAndroid Build Coastguard Worker void GenerateShrLong(const Location& loc, int shift); 333*795d594fSAndroid Build Coastguard Worker void GenerateUShrLong(const Location& loc, int shift); 334*795d594fSAndroid Build Coastguard Worker void GenerateMinMaxInt(LocationSummary* locations, bool is_min, DataType::Type type); 335*795d594fSAndroid Build Coastguard Worker void GenerateMinMaxFP(LocationSummary* locations, bool is_min, DataType::Type type); 336*795d594fSAndroid Build Coastguard Worker void GenerateMinMax(HBinaryOperation* minmax, bool is_min); 337*795d594fSAndroid Build Coastguard Worker 338*795d594fSAndroid Build Coastguard Worker void HandleFieldSet(HInstruction* instruction, 339*795d594fSAndroid Build Coastguard Worker const FieldInfo& field_info, 340*795d594fSAndroid Build Coastguard Worker bool value_can_be_null, 341*795d594fSAndroid Build Coastguard Worker WriteBarrierKind write_barrier_kind); 342*795d594fSAndroid Build Coastguard Worker void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); 343*795d594fSAndroid Build Coastguard Worker void HandleRotate(HBinaryOperation* rotate); 344*795d594fSAndroid Build Coastguard Worker 345*795d594fSAndroid Build Coastguard Worker // Generate a heap reference load using one register `out`: 346*795d594fSAndroid Build Coastguard Worker // 347*795d594fSAndroid Build Coastguard Worker // out <- *(out + offset) 348*795d594fSAndroid Build Coastguard Worker // 349*795d594fSAndroid Build Coastguard Worker // while honoring heap poisoning and/or read barriers (if any). 350*795d594fSAndroid Build Coastguard Worker // 351*795d594fSAndroid Build Coastguard Worker // Location `maybe_temp` is used when generating a read barrier and 352*795d594fSAndroid Build Coastguard Worker // shall be a register in that case; it may be an invalid location 353*795d594fSAndroid Build Coastguard Worker // otherwise. 354*795d594fSAndroid Build Coastguard Worker void GenerateReferenceLoadOneRegister(HInstruction* instruction, 355*795d594fSAndroid Build Coastguard Worker Location out, 356*795d594fSAndroid Build Coastguard Worker uint32_t offset, 357*795d594fSAndroid Build Coastguard Worker Location maybe_temp, 358*795d594fSAndroid Build Coastguard Worker ReadBarrierOption read_barrier_option); 359*795d594fSAndroid Build Coastguard Worker // Generate a heap reference load using two different registers 360*795d594fSAndroid Build Coastguard Worker // `out` and `obj`: 361*795d594fSAndroid Build Coastguard Worker // 362*795d594fSAndroid Build Coastguard Worker // out <- *(obj + offset) 363*795d594fSAndroid Build Coastguard Worker // 364*795d594fSAndroid Build Coastguard Worker // while honoring heap poisoning and/or read barriers (if any). 365*795d594fSAndroid Build Coastguard Worker // 366*795d594fSAndroid Build Coastguard Worker // Location `maybe_temp` is used when generating a Baker's (fast 367*795d594fSAndroid Build Coastguard Worker // path) read barrier and shall be a register in that case; it may 368*795d594fSAndroid Build Coastguard Worker // be an invalid location otherwise. 369*795d594fSAndroid Build Coastguard Worker void GenerateReferenceLoadTwoRegisters(HInstruction* instruction, 370*795d594fSAndroid Build Coastguard Worker Location out, 371*795d594fSAndroid Build Coastguard Worker Location obj, 372*795d594fSAndroid Build Coastguard Worker uint32_t offset, 373*795d594fSAndroid Build Coastguard Worker ReadBarrierOption read_barrier_option); 374*795d594fSAndroid Build Coastguard Worker 375*795d594fSAndroid Build Coastguard Worker // Push value to FPU stack. `is_fp` specifies whether the value is floating point or not. 376*795d594fSAndroid Build Coastguard Worker // `is_wide` specifies whether it is long/double or not. 377*795d594fSAndroid Build Coastguard Worker void PushOntoFPStack(Location source, uint32_t temp_offset, 378*795d594fSAndroid Build Coastguard Worker uint32_t stack_adjustment, bool is_fp, bool is_wide); 379*795d594fSAndroid Build Coastguard Worker 380*795d594fSAndroid Build Coastguard Worker template<class LabelType> 381*795d594fSAndroid Build Coastguard Worker void GenerateTestAndBranch(HInstruction* instruction, 382*795d594fSAndroid Build Coastguard Worker size_t condition_input_index, 383*795d594fSAndroid Build Coastguard Worker LabelType* true_target, 384*795d594fSAndroid Build Coastguard Worker LabelType* false_target); 385*795d594fSAndroid Build Coastguard Worker template<class LabelType> 386*795d594fSAndroid Build Coastguard Worker void GenerateCompareTestAndBranch(HCondition* condition, 387*795d594fSAndroid Build Coastguard Worker LabelType* true_target, 388*795d594fSAndroid Build Coastguard Worker LabelType* false_target); 389*795d594fSAndroid Build Coastguard Worker template<class LabelType> 390*795d594fSAndroid Build Coastguard Worker void GenerateFPJumps(HCondition* cond, LabelType* true_label, LabelType* false_label); 391*795d594fSAndroid Build Coastguard Worker template<class LabelType> 392*795d594fSAndroid Build Coastguard Worker void GenerateLongComparesAndJumps(HCondition* cond, 393*795d594fSAndroid Build Coastguard Worker LabelType* true_label, 394*795d594fSAndroid Build Coastguard Worker LabelType* false_label); 395*795d594fSAndroid Build Coastguard Worker 396*795d594fSAndroid Build Coastguard Worker void HandleGoto(HInstruction* got, HBasicBlock* successor); 397*795d594fSAndroid Build Coastguard Worker void GenPackedSwitchWithCompares(Register value_reg, 398*795d594fSAndroid Build Coastguard Worker int32_t lower_bound, 399*795d594fSAndroid Build Coastguard Worker uint32_t num_entries, 400*795d594fSAndroid Build Coastguard Worker HBasicBlock* switch_block, 401*795d594fSAndroid Build Coastguard Worker HBasicBlock* default_block); 402*795d594fSAndroid Build Coastguard Worker 403*795d594fSAndroid Build Coastguard Worker void GenerateFPCompare(Location lhs, Location rhs, HInstruction* insn, bool is_double); 404*795d594fSAndroid Build Coastguard Worker bool CpuHasAvxFeatureFlag(); 405*795d594fSAndroid Build Coastguard Worker bool CpuHasAvx2FeatureFlag(); 406*795d594fSAndroid Build Coastguard Worker 407*795d594fSAndroid Build Coastguard Worker void GenerateMethodEntryExitHook(HInstruction* instruction); 408*795d594fSAndroid Build Coastguard Worker 409*795d594fSAndroid Build Coastguard Worker X86Assembler* const assembler_; 410*795d594fSAndroid Build Coastguard Worker CodeGeneratorX86* const codegen_; 411*795d594fSAndroid Build Coastguard Worker 412*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86); 413*795d594fSAndroid Build Coastguard Worker }; 414*795d594fSAndroid Build Coastguard Worker 415*795d594fSAndroid Build Coastguard Worker class JumpTableRIPFixup; 416*795d594fSAndroid Build Coastguard Worker 417*795d594fSAndroid Build Coastguard Worker class CodeGeneratorX86 : public CodeGenerator { 418*795d594fSAndroid Build Coastguard Worker public: 419*795d594fSAndroid Build Coastguard Worker CodeGeneratorX86(HGraph* graph, 420*795d594fSAndroid Build Coastguard Worker const CompilerOptions& compiler_options, 421*795d594fSAndroid Build Coastguard Worker OptimizingCompilerStats* stats = nullptr); ~CodeGeneratorX86()422*795d594fSAndroid Build Coastguard Worker virtual ~CodeGeneratorX86() {} 423*795d594fSAndroid Build Coastguard Worker 424*795d594fSAndroid Build Coastguard Worker void GenerateFrameEntry() override; 425*795d594fSAndroid Build Coastguard Worker void GenerateFrameExit() override; 426*795d594fSAndroid Build Coastguard Worker void Bind(HBasicBlock* block) override; 427*795d594fSAndroid Build Coastguard Worker void MoveConstant(Location destination, int32_t value) override; 428*795d594fSAndroid Build Coastguard Worker void MoveLocation(Location dst, Location src, DataType::Type dst_type) override; 429*795d594fSAndroid Build Coastguard Worker void AddLocationAsTemp(Location location, LocationSummary* locations) override; 430*795d594fSAndroid Build Coastguard Worker 431*795d594fSAndroid Build Coastguard Worker size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) override; 432*795d594fSAndroid Build Coastguard Worker size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) override; 433*795d594fSAndroid Build Coastguard Worker size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) override; 434*795d594fSAndroid Build Coastguard Worker size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) override; 435*795d594fSAndroid Build Coastguard Worker 436*795d594fSAndroid Build Coastguard Worker // Generate code to invoke a runtime entry point. 437*795d594fSAndroid Build Coastguard Worker void InvokeRuntime(QuickEntrypointEnum entrypoint, 438*795d594fSAndroid Build Coastguard Worker HInstruction* instruction, 439*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 440*795d594fSAndroid Build Coastguard Worker SlowPathCode* slow_path = nullptr) override; 441*795d594fSAndroid Build Coastguard Worker 442*795d594fSAndroid Build Coastguard Worker // Generate code to invoke a runtime entry point, but do not record 443*795d594fSAndroid Build Coastguard Worker // PC-related information in a stack map. 444*795d594fSAndroid Build Coastguard Worker void InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset, 445*795d594fSAndroid Build Coastguard Worker HInstruction* instruction, 446*795d594fSAndroid Build Coastguard Worker SlowPathCode* slow_path); 447*795d594fSAndroid Build Coastguard Worker 448*795d594fSAndroid Build Coastguard Worker void GenerateInvokeRuntime(int32_t entry_point_offset); 449*795d594fSAndroid Build Coastguard Worker GetWordSize()450*795d594fSAndroid Build Coastguard Worker size_t GetWordSize() const override { 451*795d594fSAndroid Build Coastguard Worker return kX86WordSize; 452*795d594fSAndroid Build Coastguard Worker } 453*795d594fSAndroid Build Coastguard Worker GetSlowPathFPWidth()454*795d594fSAndroid Build Coastguard Worker size_t GetSlowPathFPWidth() const override { 455*795d594fSAndroid Build Coastguard Worker return GetGraph()->HasSIMD() 456*795d594fSAndroid Build Coastguard Worker ? GetSIMDRegisterWidth() 457*795d594fSAndroid Build Coastguard Worker : 2 * kX86WordSize; // 8 bytes == 2 words for each spill 458*795d594fSAndroid Build Coastguard Worker } 459*795d594fSAndroid Build Coastguard Worker GetCalleePreservedFPWidth()460*795d594fSAndroid Build Coastguard Worker size_t GetCalleePreservedFPWidth() const override { 461*795d594fSAndroid Build Coastguard Worker return 2 * kX86WordSize; 462*795d594fSAndroid Build Coastguard Worker } 463*795d594fSAndroid Build Coastguard Worker GetSIMDRegisterWidth()464*795d594fSAndroid Build Coastguard Worker size_t GetSIMDRegisterWidth() const override { 465*795d594fSAndroid Build Coastguard Worker return 4 * kX86WordSize; 466*795d594fSAndroid Build Coastguard Worker } 467*795d594fSAndroid Build Coastguard Worker GetLocationBuilder()468*795d594fSAndroid Build Coastguard Worker HGraphVisitor* GetLocationBuilder() override { 469*795d594fSAndroid Build Coastguard Worker return &location_builder_; 470*795d594fSAndroid Build Coastguard Worker } 471*795d594fSAndroid Build Coastguard Worker GetInstructionVisitor()472*795d594fSAndroid Build Coastguard Worker HGraphVisitor* GetInstructionVisitor() override { 473*795d594fSAndroid Build Coastguard Worker return &instruction_visitor_; 474*795d594fSAndroid Build Coastguard Worker } 475*795d594fSAndroid Build Coastguard Worker GetAssembler()476*795d594fSAndroid Build Coastguard Worker X86Assembler* GetAssembler() override { 477*795d594fSAndroid Build Coastguard Worker return &assembler_; 478*795d594fSAndroid Build Coastguard Worker } 479*795d594fSAndroid Build Coastguard Worker GetAssembler()480*795d594fSAndroid Build Coastguard Worker const X86Assembler& GetAssembler() const override { 481*795d594fSAndroid Build Coastguard Worker return assembler_; 482*795d594fSAndroid Build Coastguard Worker } 483*795d594fSAndroid Build Coastguard Worker GetAddressOf(HBasicBlock * block)484*795d594fSAndroid Build Coastguard Worker uintptr_t GetAddressOf(HBasicBlock* block) override { 485*795d594fSAndroid Build Coastguard Worker return GetLabelOf(block)->Position(); 486*795d594fSAndroid Build Coastguard Worker } 487*795d594fSAndroid Build Coastguard Worker 488*795d594fSAndroid Build Coastguard Worker void SetupBlockedRegisters() const override; 489*795d594fSAndroid Build Coastguard Worker 490*795d594fSAndroid Build Coastguard Worker void DumpCoreRegister(std::ostream& stream, int reg) const override; 491*795d594fSAndroid Build Coastguard Worker void DumpFloatingPointRegister(std::ostream& stream, int reg) const override; 492*795d594fSAndroid Build Coastguard Worker GetMoveResolver()493*795d594fSAndroid Build Coastguard Worker ParallelMoveResolverX86* GetMoveResolver() override { 494*795d594fSAndroid Build Coastguard Worker return &move_resolver_; 495*795d594fSAndroid Build Coastguard Worker } 496*795d594fSAndroid Build Coastguard Worker GetInstructionSet()497*795d594fSAndroid Build Coastguard Worker InstructionSet GetInstructionSet() const override { 498*795d594fSAndroid Build Coastguard Worker return InstructionSet::kX86; 499*795d594fSAndroid Build Coastguard Worker } 500*795d594fSAndroid Build Coastguard Worker 501*795d594fSAndroid Build Coastguard Worker const X86InstructionSetFeatures& GetInstructionSetFeatures() const; 502*795d594fSAndroid Build Coastguard Worker 503*795d594fSAndroid Build Coastguard Worker // Helper method to move a 32bits value between two locations. 504*795d594fSAndroid Build Coastguard Worker void Move32(Location destination, Location source); 505*795d594fSAndroid Build Coastguard Worker // Helper method to move a 64bits value between two locations. 506*795d594fSAndroid Build Coastguard Worker void Move64(Location destination, Location source); 507*795d594fSAndroid Build Coastguard Worker // Helper method to load a value from an address to a register. 508*795d594fSAndroid Build Coastguard Worker void LoadFromMemoryNoBarrier(DataType::Type dst_type, 509*795d594fSAndroid Build Coastguard Worker Location dst, 510*795d594fSAndroid Build Coastguard Worker Address src, 511*795d594fSAndroid Build Coastguard Worker HInstruction* instr = nullptr, 512*795d594fSAndroid Build Coastguard Worker XmmRegister temp = kNoXmmRegister, 513*795d594fSAndroid Build Coastguard Worker bool is_atomic_load = false); 514*795d594fSAndroid Build Coastguard Worker // Helper method to move a primitive value from a location to an address. 515*795d594fSAndroid Build Coastguard Worker void MoveToMemory(DataType::Type src_type, 516*795d594fSAndroid Build Coastguard Worker Location src, 517*795d594fSAndroid Build Coastguard Worker Register dst_base, 518*795d594fSAndroid Build Coastguard Worker Register dst_index = Register::kNoRegister, 519*795d594fSAndroid Build Coastguard Worker ScaleFactor dst_scale = TIMES_1, 520*795d594fSAndroid Build Coastguard Worker int32_t dst_disp = 0); 521*795d594fSAndroid Build Coastguard Worker 522*795d594fSAndroid Build Coastguard Worker // Check if the desired_string_load_kind is supported. If it is, return it, 523*795d594fSAndroid Build Coastguard Worker // otherwise return a fall-back kind that should be used instead. 524*795d594fSAndroid Build Coastguard Worker HLoadString::LoadKind GetSupportedLoadStringKind( 525*795d594fSAndroid Build Coastguard Worker HLoadString::LoadKind desired_string_load_kind) override; 526*795d594fSAndroid Build Coastguard Worker 527*795d594fSAndroid Build Coastguard Worker // Check if the desired_class_load_kind is supported. If it is, return it, 528*795d594fSAndroid Build Coastguard Worker // otherwise return a fall-back kind that should be used instead. 529*795d594fSAndroid Build Coastguard Worker HLoadClass::LoadKind GetSupportedLoadClassKind( 530*795d594fSAndroid Build Coastguard Worker HLoadClass::LoadKind desired_class_load_kind) override; 531*795d594fSAndroid Build Coastguard Worker 532*795d594fSAndroid Build Coastguard Worker // Check if the desired_dispatch_info is supported. If it is, return it, 533*795d594fSAndroid Build Coastguard Worker // otherwise return a fall-back info that should be used instead. 534*795d594fSAndroid Build Coastguard Worker HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch( 535*795d594fSAndroid Build Coastguard Worker const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info, 536*795d594fSAndroid Build Coastguard Worker ArtMethod* method) override; 537*795d594fSAndroid Build Coastguard Worker 538*795d594fSAndroid Build Coastguard Worker void LoadMethod(MethodLoadKind load_kind, Location temp, HInvoke* invoke); 539*795d594fSAndroid Build Coastguard Worker // Generate a call to a static or direct method. 540*795d594fSAndroid Build Coastguard Worker void GenerateStaticOrDirectCall( 541*795d594fSAndroid Build Coastguard Worker HInvokeStaticOrDirect* invoke, Location temp, SlowPathCode* slow_path = nullptr) override; 542*795d594fSAndroid Build Coastguard Worker // Generate a call to a virtual method. 543*795d594fSAndroid Build Coastguard Worker void GenerateVirtualCall( 544*795d594fSAndroid Build Coastguard Worker HInvokeVirtual* invoke, Location temp, SlowPathCode* slow_path = nullptr) override; 545*795d594fSAndroid Build Coastguard Worker 546*795d594fSAndroid Build Coastguard Worker void RecordBootImageIntrinsicPatch(HX86ComputeBaseMethodAddress* method_address, 547*795d594fSAndroid Build Coastguard Worker uint32_t intrinsic_data); 548*795d594fSAndroid Build Coastguard Worker void RecordBootImageRelRoPatch(HX86ComputeBaseMethodAddress* method_address, 549*795d594fSAndroid Build Coastguard Worker uint32_t boot_image_offset); 550*795d594fSAndroid Build Coastguard Worker void RecordBootImageMethodPatch(HInvoke* invoke); 551*795d594fSAndroid Build Coastguard Worker void RecordAppImageMethodPatch(HInvoke* invoke); 552*795d594fSAndroid Build Coastguard Worker void RecordMethodBssEntryPatch(HInvoke* invoke); 553*795d594fSAndroid Build Coastguard Worker void RecordBootImageTypePatch(HLoadClass* load_class); 554*795d594fSAndroid Build Coastguard Worker void RecordAppImageTypePatch(HLoadClass* load_class); 555*795d594fSAndroid Build Coastguard Worker Label* NewTypeBssEntryPatch(HLoadClass* load_class); 556*795d594fSAndroid Build Coastguard Worker void RecordBootImageStringPatch(HLoadString* load_string); 557*795d594fSAndroid Build Coastguard Worker Label* NewStringBssEntryPatch(HLoadString* load_string); 558*795d594fSAndroid Build Coastguard Worker void RecordBootImageJniEntrypointPatch(HInvokeStaticOrDirect* invoke); 559*795d594fSAndroid Build Coastguard Worker 560*795d594fSAndroid Build Coastguard Worker void LoadBootImageAddress(Register reg, 561*795d594fSAndroid Build Coastguard Worker uint32_t boot_image_reference, 562*795d594fSAndroid Build Coastguard Worker HInvokeStaticOrDirect* invoke); 563*795d594fSAndroid Build Coastguard Worker void LoadIntrinsicDeclaringClass(Register reg, HInvokeStaticOrDirect* invoke); 564*795d594fSAndroid Build Coastguard Worker 565*795d594fSAndroid Build Coastguard Worker Label* NewJitRootStringPatch(const DexFile& dex_file, 566*795d594fSAndroid Build Coastguard Worker dex::StringIndex string_index, 567*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> handle); 568*795d594fSAndroid Build Coastguard Worker Label* NewJitRootClassPatch(const DexFile& dex_file, 569*795d594fSAndroid Build Coastguard Worker dex::TypeIndex type_index, 570*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> handle); 571*795d594fSAndroid Build Coastguard Worker 572*795d594fSAndroid Build Coastguard Worker void MoveFromReturnRegister(Location trg, DataType::Type type) override; 573*795d594fSAndroid Build Coastguard Worker 574*795d594fSAndroid Build Coastguard Worker // Emit linker patches. 575*795d594fSAndroid Build Coastguard Worker void EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linker_patches) override; 576*795d594fSAndroid Build Coastguard Worker 577*795d594fSAndroid Build Coastguard Worker void PatchJitRootUse(uint8_t* code, 578*795d594fSAndroid Build Coastguard Worker const uint8_t* roots_data, 579*795d594fSAndroid Build Coastguard Worker const PatchInfo<Label>& info, 580*795d594fSAndroid Build Coastguard Worker uint64_t index_in_table) const; 581*795d594fSAndroid Build Coastguard Worker void EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) override; 582*795d594fSAndroid Build Coastguard Worker 583*795d594fSAndroid Build Coastguard Worker // Emit a write barrier if: 584*795d594fSAndroid Build Coastguard Worker // A) emit_null_check is false 585*795d594fSAndroid Build Coastguard Worker // B) emit_null_check is true, and value is not null. 586*795d594fSAndroid Build Coastguard Worker void MaybeMarkGCCard( 587*795d594fSAndroid Build Coastguard Worker Register temp, Register card, Register object, Register value, bool emit_null_check); 588*795d594fSAndroid Build Coastguard Worker 589*795d594fSAndroid Build Coastguard Worker // Emit a write barrier unconditionally. 590*795d594fSAndroid Build Coastguard Worker void MarkGCCard(Register temp, Register card, Register object); 591*795d594fSAndroid Build Coastguard Worker 592*795d594fSAndroid Build Coastguard Worker // Crash if the card table is not valid. This check is only emitted for the CC GC. We assert 593*795d594fSAndroid Build Coastguard Worker // `(!clean || !self->is_gc_marking)`, since the card table should not be set to clean when the CC 594*795d594fSAndroid Build Coastguard Worker // GC is marking for eliminated write barriers. 595*795d594fSAndroid Build Coastguard Worker void CheckGCCardIsValid(Register temp, Register card, Register object); 596*795d594fSAndroid Build Coastguard Worker 597*795d594fSAndroid Build Coastguard Worker void GenerateMemoryBarrier(MemBarrierKind kind); 598*795d594fSAndroid Build Coastguard Worker GetLabelOf(HBasicBlock * block)599*795d594fSAndroid Build Coastguard Worker Label* GetLabelOf(HBasicBlock* block) const { 600*795d594fSAndroid Build Coastguard Worker return CommonGetLabelOf<Label>(block_labels_, block); 601*795d594fSAndroid Build Coastguard Worker } 602*795d594fSAndroid Build Coastguard Worker Initialize()603*795d594fSAndroid Build Coastguard Worker void Initialize() override { 604*795d594fSAndroid Build Coastguard Worker block_labels_ = CommonInitializeLabels<Label>(); 605*795d594fSAndroid Build Coastguard Worker } 606*795d594fSAndroid Build Coastguard Worker NeedsTwoRegisters(DataType::Type type)607*795d594fSAndroid Build Coastguard Worker bool NeedsTwoRegisters(DataType::Type type) const override { 608*795d594fSAndroid Build Coastguard Worker return type == DataType::Type::kInt64; 609*795d594fSAndroid Build Coastguard Worker } 610*795d594fSAndroid Build Coastguard Worker ShouldSplitLongMoves()611*795d594fSAndroid Build Coastguard Worker bool ShouldSplitLongMoves() const override { return true; } 612*795d594fSAndroid Build Coastguard Worker GetFrameEntryLabel()613*795d594fSAndroid Build Coastguard Worker Label* GetFrameEntryLabel() { return &frame_entry_label_; } 614*795d594fSAndroid Build Coastguard Worker AddMethodAddressOffset(HX86ComputeBaseMethodAddress * method_base,int32_t offset)615*795d594fSAndroid Build Coastguard Worker void AddMethodAddressOffset(HX86ComputeBaseMethodAddress* method_base, int32_t offset) { 616*795d594fSAndroid Build Coastguard Worker method_address_offset_.Put(method_base->GetId(), offset); 617*795d594fSAndroid Build Coastguard Worker } 618*795d594fSAndroid Build Coastguard Worker GetMethodAddressOffset(HX86ComputeBaseMethodAddress * method_base)619*795d594fSAndroid Build Coastguard Worker int32_t GetMethodAddressOffset(HX86ComputeBaseMethodAddress* method_base) const { 620*795d594fSAndroid Build Coastguard Worker return method_address_offset_.Get(method_base->GetId()); 621*795d594fSAndroid Build Coastguard Worker } 622*795d594fSAndroid Build Coastguard Worker ConstantAreaStart()623*795d594fSAndroid Build Coastguard Worker int32_t ConstantAreaStart() const { 624*795d594fSAndroid Build Coastguard Worker return constant_area_start_; 625*795d594fSAndroid Build Coastguard Worker } 626*795d594fSAndroid Build Coastguard Worker 627*795d594fSAndroid Build Coastguard Worker Address LiteralDoubleAddress(double v, HX86ComputeBaseMethodAddress* method_base, Register reg); 628*795d594fSAndroid Build Coastguard Worker Address LiteralFloatAddress(float v, HX86ComputeBaseMethodAddress* method_base, Register reg); 629*795d594fSAndroid Build Coastguard Worker Address LiteralInt32Address(int32_t v, HX86ComputeBaseMethodAddress* method_base, Register reg); 630*795d594fSAndroid Build Coastguard Worker Address LiteralInt64Address(int64_t v, HX86ComputeBaseMethodAddress* method_base, Register reg); 631*795d594fSAndroid Build Coastguard Worker 632*795d594fSAndroid Build Coastguard Worker // Load a 32-bit value into a register in the most efficient manner. 633*795d594fSAndroid Build Coastguard Worker void Load32BitValue(Register dest, int32_t value); 634*795d594fSAndroid Build Coastguard Worker 635*795d594fSAndroid Build Coastguard Worker // Compare a register with a 32-bit value in the most efficient manner. 636*795d594fSAndroid Build Coastguard Worker void Compare32BitValue(Register dest, int32_t value); 637*795d594fSAndroid Build Coastguard Worker 638*795d594fSAndroid Build Coastguard Worker // Compare int values. Supports only register locations for `lhs`. 639*795d594fSAndroid Build Coastguard Worker void GenerateIntCompare(Location lhs, Location rhs); 640*795d594fSAndroid Build Coastguard Worker void GenerateIntCompare(Register lhs, Location rhs); 641*795d594fSAndroid Build Coastguard Worker 642*795d594fSAndroid Build Coastguard Worker // Construct address for array access. 643*795d594fSAndroid Build Coastguard Worker static Address ArrayAddress(Register obj, 644*795d594fSAndroid Build Coastguard Worker Location index, 645*795d594fSAndroid Build Coastguard Worker ScaleFactor scale, 646*795d594fSAndroid Build Coastguard Worker uint32_t data_offset); 647*795d594fSAndroid Build Coastguard Worker 648*795d594fSAndroid Build Coastguard Worker Address LiteralCaseTable(HX86PackedSwitch* switch_instr, Register reg, Register value); 649*795d594fSAndroid Build Coastguard Worker 650*795d594fSAndroid Build Coastguard Worker void Finalize() override; 651*795d594fSAndroid Build Coastguard Worker 652*795d594fSAndroid Build Coastguard Worker // Fast path implementation of ReadBarrier::Barrier for a heap 653*795d594fSAndroid Build Coastguard Worker // reference field load when Baker's read barriers are used. 654*795d594fSAndroid Build Coastguard Worker void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction, 655*795d594fSAndroid Build Coastguard Worker Location ref, 656*795d594fSAndroid Build Coastguard Worker Register obj, 657*795d594fSAndroid Build Coastguard Worker uint32_t offset, 658*795d594fSAndroid Build Coastguard Worker bool needs_null_check); 659*795d594fSAndroid Build Coastguard Worker // Fast path implementation of ReadBarrier::Barrier for a heap 660*795d594fSAndroid Build Coastguard Worker // reference array load when Baker's read barriers are used. 661*795d594fSAndroid Build Coastguard Worker void GenerateArrayLoadWithBakerReadBarrier(HInstruction* instruction, 662*795d594fSAndroid Build Coastguard Worker Location ref, 663*795d594fSAndroid Build Coastguard Worker Register obj, 664*795d594fSAndroid Build Coastguard Worker uint32_t data_offset, 665*795d594fSAndroid Build Coastguard Worker Location index, 666*795d594fSAndroid Build Coastguard Worker bool needs_null_check); 667*795d594fSAndroid Build Coastguard Worker // Factored implementation, used by GenerateFieldLoadWithBakerReadBarrier, 668*795d594fSAndroid Build Coastguard Worker // GenerateArrayLoadWithBakerReadBarrier and some intrinsics. 669*795d594fSAndroid Build Coastguard Worker // 670*795d594fSAndroid Build Coastguard Worker // Load the object reference located at address `src`, held by 671*795d594fSAndroid Build Coastguard Worker // object `obj`, into `ref`, and mark it if needed. The base of 672*795d594fSAndroid Build Coastguard Worker // address `src` must be `obj`. 673*795d594fSAndroid Build Coastguard Worker // 674*795d594fSAndroid Build Coastguard Worker // If `always_update_field` is true, the value of the reference is 675*795d594fSAndroid Build Coastguard Worker // atomically updated in the holder (`obj`). This operation 676*795d594fSAndroid Build Coastguard Worker // requires a temporary register, which must be provided as a 677*795d594fSAndroid Build Coastguard Worker // non-null pointer (`temp`). 678*795d594fSAndroid Build Coastguard Worker void GenerateReferenceLoadWithBakerReadBarrier(HInstruction* instruction, 679*795d594fSAndroid Build Coastguard Worker Location ref, 680*795d594fSAndroid Build Coastguard Worker Register obj, 681*795d594fSAndroid Build Coastguard Worker const Address& src, 682*795d594fSAndroid Build Coastguard Worker bool needs_null_check, 683*795d594fSAndroid Build Coastguard Worker bool always_update_field = false, 684*795d594fSAndroid Build Coastguard Worker Register* temp = nullptr); 685*795d594fSAndroid Build Coastguard Worker 686*795d594fSAndroid Build Coastguard Worker // Generate a read barrier for a heap reference within `instruction` 687*795d594fSAndroid Build Coastguard Worker // using a slow path. 688*795d594fSAndroid Build Coastguard Worker // 689*795d594fSAndroid Build Coastguard Worker // A read barrier for an object reference read from the heap is 690*795d594fSAndroid Build Coastguard Worker // implemented as a call to the artReadBarrierSlow runtime entry 691*795d594fSAndroid Build Coastguard Worker // point, which is passed the values in locations `ref`, `obj`, and 692*795d594fSAndroid Build Coastguard Worker // `offset`: 693*795d594fSAndroid Build Coastguard Worker // 694*795d594fSAndroid Build Coastguard Worker // mirror::Object* artReadBarrierSlow(mirror::Object* ref, 695*795d594fSAndroid Build Coastguard Worker // mirror::Object* obj, 696*795d594fSAndroid Build Coastguard Worker // uint32_t offset); 697*795d594fSAndroid Build Coastguard Worker // 698*795d594fSAndroid Build Coastguard Worker // The `out` location contains the value returned by 699*795d594fSAndroid Build Coastguard Worker // artReadBarrierSlow. 700*795d594fSAndroid Build Coastguard Worker // 701*795d594fSAndroid Build Coastguard Worker // When `index` is provided (i.e. for array accesses), the offset 702*795d594fSAndroid Build Coastguard Worker // value passed to artReadBarrierSlow is adjusted to take `index` 703*795d594fSAndroid Build Coastguard Worker // into account. 704*795d594fSAndroid Build Coastguard Worker void GenerateReadBarrierSlow(HInstruction* instruction, 705*795d594fSAndroid Build Coastguard Worker Location out, 706*795d594fSAndroid Build Coastguard Worker Location ref, 707*795d594fSAndroid Build Coastguard Worker Location obj, 708*795d594fSAndroid Build Coastguard Worker uint32_t offset, 709*795d594fSAndroid Build Coastguard Worker Location index = Location::NoLocation()); 710*795d594fSAndroid Build Coastguard Worker 711*795d594fSAndroid Build Coastguard Worker // If read barriers are enabled, generate a read barrier for a heap 712*795d594fSAndroid Build Coastguard Worker // reference using a slow path. If heap poisoning is enabled, also 713*795d594fSAndroid Build Coastguard Worker // unpoison the reference in `out`. 714*795d594fSAndroid Build Coastguard Worker void MaybeGenerateReadBarrierSlow(HInstruction* instruction, 715*795d594fSAndroid Build Coastguard Worker Location out, 716*795d594fSAndroid Build Coastguard Worker Location ref, 717*795d594fSAndroid Build Coastguard Worker Location obj, 718*795d594fSAndroid Build Coastguard Worker uint32_t offset, 719*795d594fSAndroid Build Coastguard Worker Location index = Location::NoLocation()); 720*795d594fSAndroid Build Coastguard Worker 721*795d594fSAndroid Build Coastguard Worker // Generate a read barrier for a GC root within `instruction` using 722*795d594fSAndroid Build Coastguard Worker // a slow path. 723*795d594fSAndroid Build Coastguard Worker // 724*795d594fSAndroid Build Coastguard Worker // A read barrier for an object reference GC root is implemented as 725*795d594fSAndroid Build Coastguard Worker // a call to the artReadBarrierForRootSlow runtime entry point, 726*795d594fSAndroid Build Coastguard Worker // which is passed the value in location `root`: 727*795d594fSAndroid Build Coastguard Worker // 728*795d594fSAndroid Build Coastguard Worker // mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root); 729*795d594fSAndroid Build Coastguard Worker // 730*795d594fSAndroid Build Coastguard Worker // The `out` location contains the value returned by 731*795d594fSAndroid Build Coastguard Worker // artReadBarrierForRootSlow. 732*795d594fSAndroid Build Coastguard Worker void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root); 733*795d594fSAndroid Build Coastguard Worker 734*795d594fSAndroid Build Coastguard Worker // Ensure that prior stores complete to memory before subsequent loads. 735*795d594fSAndroid Build Coastguard Worker // The locked add implementation will avoid serializing device memory, but will 736*795d594fSAndroid Build Coastguard Worker // touch (but not change) the top of the stack. 737*795d594fSAndroid Build Coastguard Worker // The 'non_temporal' parameter should be used to ensure ordering of non-temporal stores. 738*795d594fSAndroid Build Coastguard Worker void MemoryFence(bool non_temporal = false) { 739*795d594fSAndroid Build Coastguard Worker if (!non_temporal) { 740*795d594fSAndroid Build Coastguard Worker assembler_.lock()->addl(Address(ESP, 0), Immediate(0)); 741*795d594fSAndroid Build Coastguard Worker } else { 742*795d594fSAndroid Build Coastguard Worker assembler_.mfence(); 743*795d594fSAndroid Build Coastguard Worker } 744*795d594fSAndroid Build Coastguard Worker } 745*795d594fSAndroid Build Coastguard Worker 746*795d594fSAndroid Build Coastguard Worker void IncreaseFrame(size_t adjustment) override; 747*795d594fSAndroid Build Coastguard Worker void DecreaseFrame(size_t adjustment) override; 748*795d594fSAndroid Build Coastguard Worker 749*795d594fSAndroid Build Coastguard Worker void GenerateNop() override; 750*795d594fSAndroid Build Coastguard Worker void GenerateImplicitNullCheck(HNullCheck* instruction) override; 751*795d594fSAndroid Build Coastguard Worker void GenerateExplicitNullCheck(HNullCheck* instruction) override; 752*795d594fSAndroid Build Coastguard Worker 753*795d594fSAndroid Build Coastguard Worker void MaybeGenerateInlineCacheCheck(HInstruction* instruction, Register klass); 754*795d594fSAndroid Build Coastguard Worker void MaybeIncrementHotness(HSuspendCheck* suspend_check, bool is_frame_entry); 755*795d594fSAndroid Build Coastguard Worker 756*795d594fSAndroid Build Coastguard Worker // When we don't know the proper offset for the value, we use kPlaceholder32BitOffset. 757*795d594fSAndroid Build Coastguard Worker // The correct value will be inserted when processing Assembler fixups. 758*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kPlaceholder32BitOffset = 256; 759*795d594fSAndroid Build Coastguard Worker 760*795d594fSAndroid Build Coastguard Worker private: 761*795d594fSAndroid Build Coastguard Worker struct X86PcRelativePatchInfo : PatchInfo<Label> { X86PcRelativePatchInfoX86PcRelativePatchInfo762*795d594fSAndroid Build Coastguard Worker X86PcRelativePatchInfo(HX86ComputeBaseMethodAddress* address, 763*795d594fSAndroid Build Coastguard Worker const DexFile* target_dex_file, 764*795d594fSAndroid Build Coastguard Worker uint32_t target_index) 765*795d594fSAndroid Build Coastguard Worker : PatchInfo(target_dex_file, target_index), 766*795d594fSAndroid Build Coastguard Worker method_address(address) {} 767*795d594fSAndroid Build Coastguard Worker HX86ComputeBaseMethodAddress* method_address; 768*795d594fSAndroid Build Coastguard Worker }; 769*795d594fSAndroid Build Coastguard Worker 770*795d594fSAndroid Build Coastguard Worker template <linker::LinkerPatch (*Factory)(size_t, const DexFile*, uint32_t, uint32_t)> 771*795d594fSAndroid Build Coastguard Worker void EmitPcRelativeLinkerPatches(const ArenaDeque<X86PcRelativePatchInfo>& infos, 772*795d594fSAndroid Build Coastguard Worker ArenaVector<linker::LinkerPatch>* linker_patches); 773*795d594fSAndroid Build Coastguard Worker 774*795d594fSAndroid Build Coastguard Worker Register GetInvokeExtraParameter(HInvoke* invoke, Register temp); 775*795d594fSAndroid Build Coastguard Worker Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp); 776*795d594fSAndroid Build Coastguard Worker 777*795d594fSAndroid Build Coastguard Worker // Labels for each block that will be compiled. 778*795d594fSAndroid Build Coastguard Worker Label* block_labels_; // Indexed by block id. 779*795d594fSAndroid Build Coastguard Worker Label frame_entry_label_; 780*795d594fSAndroid Build Coastguard Worker LocationsBuilderX86 location_builder_; 781*795d594fSAndroid Build Coastguard Worker InstructionCodeGeneratorX86 instruction_visitor_; 782*795d594fSAndroid Build Coastguard Worker ParallelMoveResolverX86 move_resolver_; 783*795d594fSAndroid Build Coastguard Worker X86Assembler assembler_; 784*795d594fSAndroid Build Coastguard Worker 785*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kBootImageLinkTimePcRelative. 786*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> boot_image_method_patches_; 787*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kAppImageRelRo. 788*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> app_image_method_patches_; 789*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kBssEntry. 790*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> method_bss_entry_patches_; 791*795d594fSAndroid Build Coastguard Worker // PC-relative type patch info for kBootImageLinkTimePcRelative. 792*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> boot_image_type_patches_; 793*795d594fSAndroid Build Coastguard Worker // PC-relative type patch info for kAppImageRelRo. 794*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> app_image_type_patches_; 795*795d594fSAndroid Build Coastguard Worker // PC-relative type patch info for kBssEntry. 796*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> type_bss_entry_patches_; 797*795d594fSAndroid Build Coastguard Worker // PC-relative public type patch info for kBssEntryPublic. 798*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> public_type_bss_entry_patches_; 799*795d594fSAndroid Build Coastguard Worker // PC-relative package type patch info for kBssEntryPackage. 800*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> package_type_bss_entry_patches_; 801*795d594fSAndroid Build Coastguard Worker // PC-relative String patch info for kBootImageLinkTimePcRelative. 802*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> boot_image_string_patches_; 803*795d594fSAndroid Build Coastguard Worker // PC-relative String patch info for kBssEntry. 804*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> string_bss_entry_patches_; 805*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kBootImageLinkTimePcRelative+kCallCriticalNative. 806*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> boot_image_jni_entrypoint_patches_; 807*795d594fSAndroid Build Coastguard Worker // PC-relative patch info for IntrinsicObjects for the boot image, 808*795d594fSAndroid Build Coastguard Worker // and for method/type/string patches for kBootImageRelRo otherwise. 809*795d594fSAndroid Build Coastguard Worker ArenaDeque<X86PcRelativePatchInfo> boot_image_other_patches_; 810*795d594fSAndroid Build Coastguard Worker 811*795d594fSAndroid Build Coastguard Worker // Patches for string root accesses in JIT compiled code. 812*795d594fSAndroid Build Coastguard Worker ArenaDeque<PatchInfo<Label>> jit_string_patches_; 813*795d594fSAndroid Build Coastguard Worker // Patches for class root accesses in JIT compiled code. 814*795d594fSAndroid Build Coastguard Worker ArenaDeque<PatchInfo<Label>> jit_class_patches_; 815*795d594fSAndroid Build Coastguard Worker 816*795d594fSAndroid Build Coastguard Worker // Offset to the start of the constant area in the assembled code. 817*795d594fSAndroid Build Coastguard Worker // Used for fixups to the constant area. 818*795d594fSAndroid Build Coastguard Worker int32_t constant_area_start_; 819*795d594fSAndroid Build Coastguard Worker 820*795d594fSAndroid Build Coastguard Worker // Fixups for jump tables that need to be patched after the constant table is generated. 821*795d594fSAndroid Build Coastguard Worker ArenaVector<JumpTableRIPFixup*> fixups_to_jump_tables_; 822*795d594fSAndroid Build Coastguard Worker 823*795d594fSAndroid Build Coastguard Worker // Maps a HX86ComputeBaseMethodAddress instruction id, to its offset in the 824*795d594fSAndroid Build Coastguard Worker // compiled code. 825*795d594fSAndroid Build Coastguard Worker ArenaSafeMap<uint32_t, int32_t> method_address_offset_; 826*795d594fSAndroid Build Coastguard Worker 827*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86); 828*795d594fSAndroid Build Coastguard Worker }; 829*795d594fSAndroid Build Coastguard Worker 830*795d594fSAndroid Build Coastguard Worker } // namespace x86 831*795d594fSAndroid Build Coastguard Worker } // namespace art 832*795d594fSAndroid Build Coastguard Worker 833*795d594fSAndroid Build Coastguard Worker #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_X86_H_ 834