1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2023 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_RISCV64_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_RISCV64_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h" 21*795d594fSAndroid Build Coastguard Worker #include "arch/riscv64/registers_riscv64.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 23*795d594fSAndroid Build Coastguard Worker #include "code_generator.h" 24*795d594fSAndroid Build Coastguard Worker #include "driver/compiler_options.h" 25*795d594fSAndroid Build Coastguard Worker #include "intrinsics_list.h" 26*795d594fSAndroid Build Coastguard Worker #include "optimizing/locations.h" 27*795d594fSAndroid Build Coastguard Worker #include "parallel_move_resolver.h" 28*795d594fSAndroid Build Coastguard Worker #include "utils/riscv64/assembler_riscv64.h" 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 31*795d594fSAndroid Build Coastguard Worker namespace riscv64 { 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker // InvokeDexCallingConvention registers 34*795d594fSAndroid Build Coastguard Worker static constexpr XRegister kParameterCoreRegisters[] = {A1, A2, A3, A4, A5, A6, A7}; 35*795d594fSAndroid Build Coastguard Worker static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker static constexpr FRegister kParameterFpuRegisters[] = {FA0, FA1, FA2, FA3, FA4, FA5, FA6, FA7}; 38*795d594fSAndroid Build Coastguard Worker static constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters); 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker // InvokeRuntimeCallingConvention registers 41*795d594fSAndroid Build Coastguard Worker static constexpr XRegister kRuntimeParameterCoreRegisters[] = {A0, A1, A2, A3, A4, A5, A6, A7}; 42*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRuntimeParameterCoreRegistersLength = 43*795d594fSAndroid Build Coastguard Worker arraysize(kRuntimeParameterCoreRegisters); 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker static constexpr FRegister kRuntimeParameterFpuRegisters[] = { 46*795d594fSAndroid Build Coastguard Worker FA0, FA1, FA2, FA3, FA4, FA5, FA6, FA7 47*795d594fSAndroid Build Coastguard Worker }; 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 // FCLASS returns a 10-bit classification mask with the two highest bits marking NaNs 52*795d594fSAndroid Build Coastguard Worker // (signaling and quiet). To detect a NaN, we can compare (either BGE or BGEU, the sign 53*795d594fSAndroid Build Coastguard Worker // bit is always clear) the result with the `kFClassNaNMinValue`. 54*795d594fSAndroid Build Coastguard Worker static_assert(kSignalingNaN == 0x100); 55*795d594fSAndroid Build Coastguard Worker static_assert(kQuietNaN == 0x200); 56*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kFClassNaNMinValue = 0x100; 57*795d594fSAndroid Build Coastguard Worker 58*795d594fSAndroid Build Coastguard Worker #define UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(V) \ 59*795d594fSAndroid Build Coastguard Worker V(FP16Ceil) \ 60*795d594fSAndroid Build Coastguard Worker V(FP16Compare) \ 61*795d594fSAndroid Build Coastguard Worker V(FP16Floor) \ 62*795d594fSAndroid Build Coastguard Worker V(FP16Rint) \ 63*795d594fSAndroid Build Coastguard Worker V(FP16ToFloat) \ 64*795d594fSAndroid Build Coastguard Worker V(FP16ToHalf) \ 65*795d594fSAndroid Build Coastguard Worker V(FP16Greater) \ 66*795d594fSAndroid Build Coastguard Worker V(FP16GreaterEquals) \ 67*795d594fSAndroid Build Coastguard Worker V(FP16Less) \ 68*795d594fSAndroid Build Coastguard Worker V(FP16LessEquals) \ 69*795d594fSAndroid Build Coastguard Worker V(FP16Min) \ 70*795d594fSAndroid Build Coastguard Worker V(FP16Max) \ 71*795d594fSAndroid Build Coastguard Worker V(StringStringIndexOf) \ 72*795d594fSAndroid Build Coastguard Worker V(StringStringIndexOfAfter) \ 73*795d594fSAndroid Build Coastguard Worker V(StringBufferAppend) \ 74*795d594fSAndroid Build Coastguard Worker V(StringBufferLength) \ 75*795d594fSAndroid Build Coastguard Worker V(StringBufferToString) \ 76*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendObject) \ 77*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendString) \ 78*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendCharSequence) \ 79*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendCharArray) \ 80*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendBoolean) \ 81*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendChar) \ 82*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendInt) \ 83*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendLong) \ 84*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendFloat) \ 85*795d594fSAndroid Build Coastguard Worker V(StringBuilderAppendDouble) \ 86*795d594fSAndroid Build Coastguard Worker V(StringBuilderLength) \ 87*795d594fSAndroid Build Coastguard Worker V(StringBuilderToString) \ 88*795d594fSAndroid Build Coastguard Worker V(CRC32Update) \ 89*795d594fSAndroid Build Coastguard Worker V(CRC32UpdateBytes) \ 90*795d594fSAndroid Build Coastguard Worker V(CRC32UpdateByteBuffer) \ 91*795d594fSAndroid Build Coastguard Worker V(MethodHandleInvokeExact) \ 92*795d594fSAndroid Build Coastguard Worker V(MethodHandleInvoke) \ 93*795d594fSAndroid Build Coastguard Worker V(UnsafeArrayBaseOffset) \ 94*795d594fSAndroid Build Coastguard Worker V(JdkUnsafeArrayBaseOffset) \ 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker // Method register on invoke. 97*795d594fSAndroid Build Coastguard Worker static const XRegister kArtMethodRegister = A0; 98*795d594fSAndroid Build Coastguard Worker 99*795d594fSAndroid Build Coastguard Worker // Helper functions used by codegen as well as intrinsics. 100*795d594fSAndroid Build Coastguard Worker XRegister InputXRegisterOrZero(Location location); 101*795d594fSAndroid Build Coastguard Worker int32_t ReadBarrierMarkEntrypointOffset(Location ref); 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker class CodeGeneratorRISCV64; 104*795d594fSAndroid Build Coastguard Worker 105*795d594fSAndroid Build Coastguard Worker class InvokeRuntimeCallingConvention : public CallingConvention<XRegister, FRegister> { 106*795d594fSAndroid Build Coastguard Worker public: InvokeRuntimeCallingConvention()107*795d594fSAndroid Build Coastguard Worker InvokeRuntimeCallingConvention() 108*795d594fSAndroid Build Coastguard Worker : CallingConvention(kRuntimeParameterCoreRegisters, 109*795d594fSAndroid Build Coastguard Worker kRuntimeParameterCoreRegistersLength, 110*795d594fSAndroid Build Coastguard Worker kRuntimeParameterFpuRegisters, 111*795d594fSAndroid Build Coastguard Worker kRuntimeParameterFpuRegistersLength, 112*795d594fSAndroid Build Coastguard Worker kRiscv64PointerSize) {} 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type return_type); 115*795d594fSAndroid Build Coastguard Worker 116*795d594fSAndroid Build Coastguard Worker private: 117*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); 118*795d594fSAndroid Build Coastguard Worker }; 119*795d594fSAndroid Build Coastguard Worker 120*795d594fSAndroid Build Coastguard Worker class InvokeDexCallingConvention : public CallingConvention<XRegister, FRegister> { 121*795d594fSAndroid Build Coastguard Worker public: InvokeDexCallingConvention()122*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConvention() 123*795d594fSAndroid Build Coastguard Worker : CallingConvention(kParameterCoreRegisters, 124*795d594fSAndroid Build Coastguard Worker kParameterCoreRegistersLength, 125*795d594fSAndroid Build Coastguard Worker kParameterFpuRegisters, 126*795d594fSAndroid Build Coastguard Worker kParameterFpuRegistersLength, 127*795d594fSAndroid Build Coastguard Worker kRiscv64PointerSize) {} 128*795d594fSAndroid Build Coastguard Worker 129*795d594fSAndroid Build Coastguard Worker private: 130*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention); 131*795d594fSAndroid Build Coastguard Worker }; 132*795d594fSAndroid Build Coastguard Worker 133*795d594fSAndroid Build Coastguard Worker class InvokeDexCallingConventionVisitorRISCV64 : public InvokeDexCallingConventionVisitor { 134*795d594fSAndroid Build Coastguard Worker public: InvokeDexCallingConventionVisitorRISCV64()135*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConventionVisitorRISCV64() {} ~InvokeDexCallingConventionVisitorRISCV64()136*795d594fSAndroid Build Coastguard Worker virtual ~InvokeDexCallingConventionVisitorRISCV64() {} 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker Location GetNextLocation(DataType::Type type) override; 139*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type type) const override; 140*795d594fSAndroid Build Coastguard Worker Location GetMethodLocation() const override; 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker private: 143*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConvention calling_convention; 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorRISCV64); 146*795d594fSAndroid Build Coastguard Worker }; 147*795d594fSAndroid Build Coastguard Worker 148*795d594fSAndroid Build Coastguard Worker class CriticalNativeCallingConventionVisitorRiscv64 : public InvokeDexCallingConventionVisitor { 149*795d594fSAndroid Build Coastguard Worker public: CriticalNativeCallingConventionVisitorRiscv64(bool for_register_allocation)150*795d594fSAndroid Build Coastguard Worker explicit CriticalNativeCallingConventionVisitorRiscv64(bool for_register_allocation) 151*795d594fSAndroid Build Coastguard Worker : for_register_allocation_(for_register_allocation) {} 152*795d594fSAndroid Build Coastguard Worker ~CriticalNativeCallingConventionVisitorRiscv64()153*795d594fSAndroid Build Coastguard Worker virtual ~CriticalNativeCallingConventionVisitorRiscv64() {} 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker Location GetNextLocation(DataType::Type type) override; 156*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type type) const override; 157*795d594fSAndroid Build Coastguard Worker Location GetMethodLocation() const override; 158*795d594fSAndroid Build Coastguard Worker GetStackOffset()159*795d594fSAndroid Build Coastguard Worker size_t GetStackOffset() const { return stack_offset_; } 160*795d594fSAndroid Build Coastguard Worker 161*795d594fSAndroid Build Coastguard Worker private: 162*795d594fSAndroid Build Coastguard Worker // Register allocator does not support adjusting frame size, so we cannot provide final locations 163*795d594fSAndroid Build Coastguard Worker // of stack arguments for register allocation. We ask the register allocator for any location and 164*795d594fSAndroid Build Coastguard Worker // move these arguments to the right place after adjusting the SP when generating the call. 165*795d594fSAndroid Build Coastguard Worker const bool for_register_allocation_; 166*795d594fSAndroid Build Coastguard Worker size_t gpr_index_ = 0u; 167*795d594fSAndroid Build Coastguard Worker size_t fpr_index_ = 0u; 168*795d594fSAndroid Build Coastguard Worker size_t stack_offset_ = 0u; 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(CriticalNativeCallingConventionVisitorRiscv64); 171*795d594fSAndroid Build Coastguard Worker }; 172*795d594fSAndroid Build Coastguard Worker 173*795d594fSAndroid Build Coastguard Worker class SlowPathCodeRISCV64 : public SlowPathCode { 174*795d594fSAndroid Build Coastguard Worker public: SlowPathCodeRISCV64(HInstruction * instruction)175*795d594fSAndroid Build Coastguard Worker explicit SlowPathCodeRISCV64(HInstruction* instruction) 176*795d594fSAndroid Build Coastguard Worker : SlowPathCode(instruction), entry_label_(), exit_label_() {} 177*795d594fSAndroid Build Coastguard Worker GetEntryLabel()178*795d594fSAndroid Build Coastguard Worker Riscv64Label* GetEntryLabel() { return &entry_label_; } GetExitLabel()179*795d594fSAndroid Build Coastguard Worker Riscv64Label* GetExitLabel() { return &exit_label_; } 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker private: 182*795d594fSAndroid Build Coastguard Worker Riscv64Label entry_label_; 183*795d594fSAndroid Build Coastguard Worker Riscv64Label exit_label_; 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(SlowPathCodeRISCV64); 186*795d594fSAndroid Build Coastguard Worker }; 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker class ParallelMoveResolverRISCV64 : public ParallelMoveResolverWithSwap { 189*795d594fSAndroid Build Coastguard Worker public: ParallelMoveResolverRISCV64(ArenaAllocator * allocator,CodeGeneratorRISCV64 * codegen)190*795d594fSAndroid Build Coastguard Worker ParallelMoveResolverRISCV64(ArenaAllocator* allocator, CodeGeneratorRISCV64* codegen) 191*795d594fSAndroid Build Coastguard Worker : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {} 192*795d594fSAndroid Build Coastguard Worker 193*795d594fSAndroid Build Coastguard Worker void EmitMove(size_t index) override; 194*795d594fSAndroid Build Coastguard Worker void EmitSwap(size_t index) override; 195*795d594fSAndroid Build Coastguard Worker void SpillScratch(int reg) override; 196*795d594fSAndroid Build Coastguard Worker void RestoreScratch(int reg) override; 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker void Exchange(int index1, int index2, bool double_slot); 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker Riscv64Assembler* GetAssembler() const; 201*795d594fSAndroid Build Coastguard Worker 202*795d594fSAndroid Build Coastguard Worker private: 203*795d594fSAndroid Build Coastguard Worker CodeGeneratorRISCV64* const codegen_; 204*795d594fSAndroid Build Coastguard Worker 205*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverRISCV64); 206*795d594fSAndroid Build Coastguard Worker }; 207*795d594fSAndroid Build Coastguard Worker 208*795d594fSAndroid Build Coastguard Worker class FieldAccessCallingConventionRISCV64 : public FieldAccessCallingConvention { 209*795d594fSAndroid Build Coastguard Worker public: FieldAccessCallingConventionRISCV64()210*795d594fSAndroid Build Coastguard Worker FieldAccessCallingConventionRISCV64() {} 211*795d594fSAndroid Build Coastguard Worker GetObjectLocation()212*795d594fSAndroid Build Coastguard Worker Location GetObjectLocation() const override { 213*795d594fSAndroid Build Coastguard Worker return Location::RegisterLocation(A1); 214*795d594fSAndroid Build Coastguard Worker } GetFieldIndexLocation()215*795d594fSAndroid Build Coastguard Worker Location GetFieldIndexLocation() const override { 216*795d594fSAndroid Build Coastguard Worker return Location::RegisterLocation(A0); 217*795d594fSAndroid Build Coastguard Worker } GetReturnLocation(DataType::Type type ATTRIBUTE_UNUSED)218*795d594fSAndroid Build Coastguard Worker Location GetReturnLocation(DataType::Type type ATTRIBUTE_UNUSED) const override { 219*795d594fSAndroid Build Coastguard Worker return Location::RegisterLocation(A0); 220*795d594fSAndroid Build Coastguard Worker } GetSetValueLocation(DataType::Type type ATTRIBUTE_UNUSED,bool is_instance)221*795d594fSAndroid Build Coastguard Worker Location GetSetValueLocation(DataType::Type type ATTRIBUTE_UNUSED, 222*795d594fSAndroid Build Coastguard Worker bool is_instance) const override { 223*795d594fSAndroid Build Coastguard Worker return is_instance 224*795d594fSAndroid Build Coastguard Worker ? Location::RegisterLocation(A2) 225*795d594fSAndroid Build Coastguard Worker : Location::RegisterLocation(A1); 226*795d594fSAndroid Build Coastguard Worker } GetFpuLocation(DataType::Type type ATTRIBUTE_UNUSED)227*795d594fSAndroid Build Coastguard Worker Location GetFpuLocation(DataType::Type type ATTRIBUTE_UNUSED) const override { 228*795d594fSAndroid Build Coastguard Worker return Location::FpuRegisterLocation(FA0); 229*795d594fSAndroid Build Coastguard Worker } 230*795d594fSAndroid Build Coastguard Worker 231*795d594fSAndroid Build Coastguard Worker private: 232*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionRISCV64); 233*795d594fSAndroid Build Coastguard Worker }; 234*795d594fSAndroid Build Coastguard Worker 235*795d594fSAndroid Build Coastguard Worker class LocationsBuilderRISCV64 : public HGraphVisitor { 236*795d594fSAndroid Build Coastguard Worker public: LocationsBuilderRISCV64(HGraph * graph,CodeGeneratorRISCV64 * codegen)237*795d594fSAndroid Build Coastguard Worker LocationsBuilderRISCV64(HGraph* graph, CodeGeneratorRISCV64* codegen) 238*795d594fSAndroid Build Coastguard Worker : HGraphVisitor(graph), codegen_(codegen) {} 239*795d594fSAndroid Build Coastguard Worker 240*795d594fSAndroid Build Coastguard Worker #define DECLARE_VISIT_INSTRUCTION(name, super) void Visit##name(H##name* instr) override; 241*795d594fSAndroid Build Coastguard Worker 242*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(DECLARE_VISIT_INSTRUCTION)243*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(DECLARE_VISIT_INSTRUCTION) 244*795d594fSAndroid Build Coastguard Worker 245*795d594fSAndroid Build Coastguard Worker #undef DECLARE_VISIT_INSTRUCTION 246*795d594fSAndroid Build Coastguard Worker 247*795d594fSAndroid Build Coastguard Worker void VisitInstruction(HInstruction* instruction) override { 248*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() << " (id " 249*795d594fSAndroid Build Coastguard Worker << instruction->GetId() << ")"; 250*795d594fSAndroid Build Coastguard Worker } 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker protected: 253*795d594fSAndroid Build Coastguard Worker void HandleInvoke(HInvoke* invoke); 254*795d594fSAndroid Build Coastguard Worker void HandleBinaryOp(HBinaryOperation* operation); 255*795d594fSAndroid Build Coastguard Worker void HandleCondition(HCondition* instruction); 256*795d594fSAndroid Build Coastguard Worker void HandleShift(HBinaryOperation* operation); 257*795d594fSAndroid Build Coastguard Worker void HandleFieldSet(HInstruction* instruction); 258*795d594fSAndroid Build Coastguard Worker void HandleFieldGet(HInstruction* instruction); 259*795d594fSAndroid Build Coastguard Worker 260*795d594fSAndroid Build Coastguard Worker InvokeDexCallingConventionVisitorRISCV64 parameter_visitor_; 261*795d594fSAndroid Build Coastguard Worker 262*795d594fSAndroid Build Coastguard Worker CodeGeneratorRISCV64* const codegen_; 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(LocationsBuilderRISCV64); 265*795d594fSAndroid Build Coastguard Worker }; 266*795d594fSAndroid Build Coastguard Worker 267*795d594fSAndroid Build Coastguard Worker class InstructionCodeGeneratorRISCV64 : public InstructionCodeGenerator { 268*795d594fSAndroid Build Coastguard Worker public: 269*795d594fSAndroid Build Coastguard Worker InstructionCodeGeneratorRISCV64(HGraph* graph, CodeGeneratorRISCV64* codegen); 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker #define DECLARE_VISIT_INSTRUCTION(name, super) void Visit##name(H##name* instr) override; 272*795d594fSAndroid Build Coastguard Worker 273*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION) FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(DECLARE_VISIT_INSTRUCTION)274*795d594fSAndroid Build Coastguard Worker FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(DECLARE_VISIT_INSTRUCTION) 275*795d594fSAndroid Build Coastguard Worker 276*795d594fSAndroid Build Coastguard Worker #undef DECLARE_VISIT_INSTRUCTION 277*795d594fSAndroid Build Coastguard Worker 278*795d594fSAndroid Build Coastguard Worker void VisitInstruction(HInstruction* instruction) override { 279*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable instruction " << instruction->DebugName() << " (id " 280*795d594fSAndroid Build Coastguard Worker << instruction->GetId() << ")"; 281*795d594fSAndroid Build Coastguard Worker } 282*795d594fSAndroid Build Coastguard Worker GetAssembler()283*795d594fSAndroid Build Coastguard Worker Riscv64Assembler* GetAssembler() const { return assembler_; } 284*795d594fSAndroid Build Coastguard Worker 285*795d594fSAndroid Build Coastguard Worker void GenerateMemoryBarrier(MemBarrierKind kind); 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker void FAdd(FRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 288*795d594fSAndroid Build Coastguard Worker void FClass(XRegister rd, FRegister rs1, DataType::Type type); 289*795d594fSAndroid Build Coastguard Worker 290*795d594fSAndroid Build Coastguard Worker void Load(Location out, XRegister rs1, int32_t offset, DataType::Type type); 291*795d594fSAndroid Build Coastguard Worker void Store(Location value, XRegister rs1, int32_t offset, DataType::Type type); 292*795d594fSAndroid Build Coastguard Worker 293*795d594fSAndroid Build Coastguard Worker // Sequentially consistent store. Used for volatile fields and intrinsics. 294*795d594fSAndroid Build Coastguard Worker // The `instruction` argument is for recording an implicit null check stack map with the 295*795d594fSAndroid Build Coastguard Worker // store instruction which may not be the last instruction emitted by `StoreSeqCst()`. 296*795d594fSAndroid Build Coastguard Worker void StoreSeqCst(Location value, 297*795d594fSAndroid Build Coastguard Worker XRegister rs1, 298*795d594fSAndroid Build Coastguard Worker int32_t offset, 299*795d594fSAndroid Build Coastguard Worker DataType::Type type, 300*795d594fSAndroid Build Coastguard Worker HInstruction* instruction = nullptr); 301*795d594fSAndroid Build Coastguard Worker 302*795d594fSAndroid Build Coastguard Worker void ShNAdd(XRegister rd, XRegister rs1, XRegister rs2, DataType::Type type); 303*795d594fSAndroid Build Coastguard Worker 304*795d594fSAndroid Build Coastguard Worker protected: 305*795d594fSAndroid Build Coastguard Worker void GenerateClassInitializationCheck(SlowPathCodeRISCV64* slow_path, XRegister class_reg); 306*795d594fSAndroid Build Coastguard Worker void GenerateBitstringTypeCheckCompare(HTypeCheckInstruction* check, XRegister temp); 307*795d594fSAndroid Build Coastguard Worker void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor); 308*795d594fSAndroid Build Coastguard Worker void HandleBinaryOp(HBinaryOperation* operation); 309*795d594fSAndroid Build Coastguard Worker void HandleCondition(HCondition* instruction); 310*795d594fSAndroid Build Coastguard Worker void HandleShift(HBinaryOperation* operation); 311*795d594fSAndroid Build Coastguard Worker void HandleFieldSet(HInstruction* instruction, 312*795d594fSAndroid Build Coastguard Worker const FieldInfo& field_info, 313*795d594fSAndroid Build Coastguard Worker bool value_can_be_null, 314*795d594fSAndroid Build Coastguard Worker WriteBarrierKind write_barrier_kind); 315*795d594fSAndroid Build Coastguard Worker void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); 316*795d594fSAndroid Build Coastguard Worker 317*795d594fSAndroid Build Coastguard Worker // Generate a heap reference load using one register `out`: 318*795d594fSAndroid Build Coastguard Worker // 319*795d594fSAndroid Build Coastguard Worker // out <- *(out + offset) 320*795d594fSAndroid Build Coastguard Worker // 321*795d594fSAndroid Build Coastguard Worker // while honoring heap poisoning and/or read barriers (if any). 322*795d594fSAndroid Build Coastguard Worker // 323*795d594fSAndroid Build Coastguard Worker // Location `maybe_temp` is used when generating a read barrier and 324*795d594fSAndroid Build Coastguard Worker // shall be a register in that case; it may be an invalid location 325*795d594fSAndroid Build Coastguard Worker // otherwise. 326*795d594fSAndroid Build Coastguard Worker void GenerateReferenceLoadOneRegister(HInstruction* instruction, 327*795d594fSAndroid Build Coastguard Worker Location out, 328*795d594fSAndroid Build Coastguard Worker uint32_t offset, 329*795d594fSAndroid Build Coastguard Worker Location maybe_temp, 330*795d594fSAndroid Build Coastguard Worker ReadBarrierOption read_barrier_option); 331*795d594fSAndroid Build Coastguard Worker // Generate a heap reference load using two different registers 332*795d594fSAndroid Build Coastguard Worker // `out` and `obj`: 333*795d594fSAndroid Build Coastguard Worker // 334*795d594fSAndroid Build Coastguard Worker // out <- *(obj + offset) 335*795d594fSAndroid Build Coastguard Worker // 336*795d594fSAndroid Build Coastguard Worker // while honoring heap poisoning and/or read barriers (if any). 337*795d594fSAndroid Build Coastguard Worker // 338*795d594fSAndroid Build Coastguard Worker // Location `maybe_temp` is used when generating a Baker's (fast 339*795d594fSAndroid Build Coastguard Worker // path) read barrier and shall be a register in that case; it may 340*795d594fSAndroid Build Coastguard Worker // be an invalid location otherwise. 341*795d594fSAndroid Build Coastguard Worker void GenerateReferenceLoadTwoRegisters(HInstruction* instruction, 342*795d594fSAndroid Build Coastguard Worker Location out, 343*795d594fSAndroid Build Coastguard Worker Location obj, 344*795d594fSAndroid Build Coastguard Worker uint32_t offset, 345*795d594fSAndroid Build Coastguard Worker Location maybe_temp, 346*795d594fSAndroid Build Coastguard Worker ReadBarrierOption read_barrier_option); 347*795d594fSAndroid Build Coastguard Worker 348*795d594fSAndroid Build Coastguard Worker void GenerateTestAndBranch(HInstruction* instruction, 349*795d594fSAndroid Build Coastguard Worker size_t condition_input_index, 350*795d594fSAndroid Build Coastguard Worker Riscv64Label* true_target, 351*795d594fSAndroid Build Coastguard Worker Riscv64Label* false_target); 352*795d594fSAndroid Build Coastguard Worker void DivRemOneOrMinusOne(HBinaryOperation* instruction); 353*795d594fSAndroid Build Coastguard Worker void DivRemByPowerOfTwo(HBinaryOperation* instruction); 354*795d594fSAndroid Build Coastguard Worker void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); 355*795d594fSAndroid Build Coastguard Worker void GenerateDivRemIntegral(HBinaryOperation* instruction); 356*795d594fSAndroid Build Coastguard Worker void GenerateIntLongCondition(IfCondition cond, LocationSummary* locations); 357*795d594fSAndroid Build Coastguard Worker void GenerateIntLongCondition(IfCondition cond, 358*795d594fSAndroid Build Coastguard Worker LocationSummary* locations, 359*795d594fSAndroid Build Coastguard Worker XRegister rd, 360*795d594fSAndroid Build Coastguard Worker bool to_all_bits); 361*795d594fSAndroid Build Coastguard Worker void GenerateIntLongCompareAndBranch(IfCondition cond, 362*795d594fSAndroid Build Coastguard Worker LocationSummary* locations, 363*795d594fSAndroid Build Coastguard Worker Riscv64Label* label); 364*795d594fSAndroid Build Coastguard Worker void GenerateFpCondition(IfCondition cond, 365*795d594fSAndroid Build Coastguard Worker bool gt_bias, 366*795d594fSAndroid Build Coastguard Worker DataType::Type type, 367*795d594fSAndroid Build Coastguard Worker LocationSummary* locations, 368*795d594fSAndroid Build Coastguard Worker Riscv64Label* label = nullptr); 369*795d594fSAndroid Build Coastguard Worker void GenerateFpCondition(IfCondition cond, 370*795d594fSAndroid Build Coastguard Worker bool gt_bias, 371*795d594fSAndroid Build Coastguard Worker DataType::Type type, 372*795d594fSAndroid Build Coastguard Worker LocationSummary* locations, 373*795d594fSAndroid Build Coastguard Worker Riscv64Label* label, 374*795d594fSAndroid Build Coastguard Worker XRegister rd, 375*795d594fSAndroid Build Coastguard Worker bool to_all_bits); 376*795d594fSAndroid Build Coastguard Worker void GenerateMethodEntryExitHook(HInstruction* instruction); 377*795d594fSAndroid Build Coastguard Worker void HandleGoto(HInstruction* got, HBasicBlock* successor); 378*795d594fSAndroid Build Coastguard Worker void GenPackedSwitchWithCompares(XRegister adjusted, 379*795d594fSAndroid Build Coastguard Worker XRegister temp, 380*795d594fSAndroid Build Coastguard Worker uint32_t num_entries, 381*795d594fSAndroid Build Coastguard Worker HBasicBlock* switch_block); 382*795d594fSAndroid Build Coastguard Worker void GenTableBasedPackedSwitch(XRegister adjusted, 383*795d594fSAndroid Build Coastguard Worker XRegister temp, 384*795d594fSAndroid Build Coastguard Worker uint32_t num_entries, 385*795d594fSAndroid Build Coastguard Worker HBasicBlock* switch_block); 386*795d594fSAndroid Build Coastguard Worker int32_t VecAddress(LocationSummary* locations, 387*795d594fSAndroid Build Coastguard Worker size_t size, 388*795d594fSAndroid Build Coastguard Worker /*out*/ XRegister* adjusted_base); 389*795d594fSAndroid Build Coastguard Worker 390*795d594fSAndroid Build Coastguard Worker template <typename Reg, 391*795d594fSAndroid Build Coastguard Worker void (Riscv64Assembler::*opS)(Reg, FRegister, FRegister), 392*795d594fSAndroid Build Coastguard Worker void (Riscv64Assembler::*opD)(Reg, FRegister, FRegister)> 393*795d594fSAndroid Build Coastguard Worker void FpBinOp(Reg rd, FRegister rs1, FRegister rs2, DataType::Type type); 394*795d594fSAndroid Build Coastguard Worker void FSub(FRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 395*795d594fSAndroid Build Coastguard Worker void FDiv(FRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 396*795d594fSAndroid Build Coastguard Worker void FMul(FRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 397*795d594fSAndroid Build Coastguard Worker void FMin(FRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 398*795d594fSAndroid Build Coastguard Worker void FMax(FRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 399*795d594fSAndroid Build Coastguard Worker void FEq(XRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 400*795d594fSAndroid Build Coastguard Worker void FLt(XRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 401*795d594fSAndroid Build Coastguard Worker void FLe(XRegister rd, FRegister rs1, FRegister rs2, DataType::Type type); 402*795d594fSAndroid Build Coastguard Worker 403*795d594fSAndroid Build Coastguard Worker template <typename Reg, 404*795d594fSAndroid Build Coastguard Worker void (Riscv64Assembler::*opS)(Reg, FRegister), 405*795d594fSAndroid Build Coastguard Worker void (Riscv64Assembler::*opD)(Reg, FRegister)> 406*795d594fSAndroid Build Coastguard Worker void FpUnOp(Reg rd, FRegister rs1, DataType::Type type); 407*795d594fSAndroid Build Coastguard Worker void FAbs(FRegister rd, FRegister rs1, DataType::Type type); 408*795d594fSAndroid Build Coastguard Worker void FNeg(FRegister rd, FRegister rs1, DataType::Type type); 409*795d594fSAndroid Build Coastguard Worker void FMv(FRegister rd, FRegister rs1, DataType::Type type); 410*795d594fSAndroid Build Coastguard Worker void FMvX(XRegister rd, FRegister rs1, DataType::Type type); 411*795d594fSAndroid Build Coastguard Worker 412*795d594fSAndroid Build Coastguard Worker Riscv64Assembler* const assembler_; 413*795d594fSAndroid Build Coastguard Worker CodeGeneratorRISCV64* const codegen_; 414*795d594fSAndroid Build Coastguard Worker 415*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorRISCV64); 416*795d594fSAndroid Build Coastguard Worker }; 417*795d594fSAndroid Build Coastguard Worker 418*795d594fSAndroid Build Coastguard Worker class CodeGeneratorRISCV64 : public CodeGenerator { 419*795d594fSAndroid Build Coastguard Worker public: 420*795d594fSAndroid Build Coastguard Worker CodeGeneratorRISCV64(HGraph* graph, 421*795d594fSAndroid Build Coastguard Worker const CompilerOptions& compiler_options, 422*795d594fSAndroid Build Coastguard Worker OptimizingCompilerStats* stats = nullptr); ~CodeGeneratorRISCV64()423*795d594fSAndroid Build Coastguard Worker virtual ~CodeGeneratorRISCV64() {} 424*795d594fSAndroid Build Coastguard Worker 425*795d594fSAndroid Build Coastguard Worker void GenerateFrameEntry() override; 426*795d594fSAndroid Build Coastguard Worker void GenerateFrameExit() override; 427*795d594fSAndroid Build Coastguard Worker 428*795d594fSAndroid Build Coastguard Worker void Bind(HBasicBlock* block) override; 429*795d594fSAndroid Build Coastguard Worker GetWordSize()430*795d594fSAndroid Build Coastguard Worker size_t GetWordSize() const override { 431*795d594fSAndroid Build Coastguard Worker // The "word" for the compiler is the core register size (64-bit for riscv64) while the 432*795d594fSAndroid Build Coastguard Worker // riscv64 assembler uses "word" for 32-bit values and "double word" for 64-bit values. 433*795d594fSAndroid Build Coastguard Worker return kRiscv64DoublewordSize; 434*795d594fSAndroid Build Coastguard Worker } 435*795d594fSAndroid Build Coastguard Worker SupportsPredicatedSIMD()436*795d594fSAndroid Build Coastguard Worker bool SupportsPredicatedSIMD() const override { 437*795d594fSAndroid Build Coastguard Worker // TODO(riscv64): Check the vector extension. 438*795d594fSAndroid Build Coastguard Worker return false; 439*795d594fSAndroid Build Coastguard Worker } 440*795d594fSAndroid Build Coastguard Worker 441*795d594fSAndroid Build Coastguard Worker // Get FP register width in bytes for spilling/restoring in the slow paths. 442*795d594fSAndroid Build Coastguard Worker // 443*795d594fSAndroid Build Coastguard Worker // Note: In SIMD graphs this should return SIMD register width as all FP and SIMD registers 444*795d594fSAndroid Build Coastguard Worker // alias and live SIMD registers are forced to be spilled in full size in the slow paths. GetSlowPathFPWidth()445*795d594fSAndroid Build Coastguard Worker size_t GetSlowPathFPWidth() const override { 446*795d594fSAndroid Build Coastguard Worker // Default implementation. 447*795d594fSAndroid Build Coastguard Worker return GetCalleePreservedFPWidth(); 448*795d594fSAndroid Build Coastguard Worker } 449*795d594fSAndroid Build Coastguard Worker GetCalleePreservedFPWidth()450*795d594fSAndroid Build Coastguard Worker size_t GetCalleePreservedFPWidth() const override { 451*795d594fSAndroid Build Coastguard Worker return kRiscv64FloatRegSizeInBytes; 452*795d594fSAndroid Build Coastguard Worker }; 453*795d594fSAndroid Build Coastguard Worker GetSIMDRegisterWidth()454*795d594fSAndroid Build Coastguard Worker size_t GetSIMDRegisterWidth() const override { 455*795d594fSAndroid Build Coastguard Worker // TODO(riscv64): Implement SIMD with the Vector extension. 456*795d594fSAndroid Build Coastguard Worker // Note: HLoopOptimization calls this function even for an ISA without SIMD support. 457*795d594fSAndroid Build Coastguard Worker return kRiscv64FloatRegSizeInBytes; 458*795d594fSAndroid Build Coastguard Worker }; 459*795d594fSAndroid Build Coastguard Worker GetAddressOf(HBasicBlock * block)460*795d594fSAndroid Build Coastguard Worker uintptr_t GetAddressOf(HBasicBlock* block) override { 461*795d594fSAndroid Build Coastguard Worker return assembler_.GetLabelLocation(GetLabelOf(block)); 462*795d594fSAndroid Build Coastguard Worker }; 463*795d594fSAndroid Build Coastguard Worker GetLabelOf(HBasicBlock * block)464*795d594fSAndroid Build Coastguard Worker Riscv64Label* GetLabelOf(HBasicBlock* block) const { 465*795d594fSAndroid Build Coastguard Worker return CommonGetLabelOf<Riscv64Label>(block_labels_, block); 466*795d594fSAndroid Build Coastguard Worker } 467*795d594fSAndroid Build Coastguard Worker Initialize()468*795d594fSAndroid Build Coastguard Worker void Initialize() override { block_labels_ = CommonInitializeLabels<Riscv64Label>(); } 469*795d594fSAndroid Build Coastguard Worker 470*795d594fSAndroid Build Coastguard Worker void MoveConstant(Location destination, int32_t value) override; 471*795d594fSAndroid Build Coastguard Worker void MoveLocation(Location destination, Location source, DataType::Type dst_type) override; 472*795d594fSAndroid Build Coastguard Worker void AddLocationAsTemp(Location location, LocationSummary* locations) override; 473*795d594fSAndroid Build Coastguard Worker GetAssembler()474*795d594fSAndroid Build Coastguard Worker Riscv64Assembler* GetAssembler() override { return &assembler_; } GetAssembler()475*795d594fSAndroid Build Coastguard Worker const Riscv64Assembler& GetAssembler() const override { return assembler_; } 476*795d594fSAndroid Build Coastguard Worker GetLocationBuilder()477*795d594fSAndroid Build Coastguard Worker HGraphVisitor* GetLocationBuilder() override { return &location_builder_; } 478*795d594fSAndroid Build Coastguard Worker GetInstructionVisitor()479*795d594fSAndroid Build Coastguard Worker InstructionCodeGeneratorRISCV64* GetInstructionVisitor() override { 480*795d594fSAndroid Build Coastguard Worker return &instruction_visitor_; 481*795d594fSAndroid Build Coastguard Worker } 482*795d594fSAndroid Build Coastguard Worker 483*795d594fSAndroid Build Coastguard Worker void MaybeGenerateInlineCacheCheck(HInstruction* instruction, XRegister klass); 484*795d594fSAndroid Build Coastguard Worker 485*795d594fSAndroid Build Coastguard Worker void SetupBlockedRegisters() const override; 486*795d594fSAndroid Build Coastguard Worker 487*795d594fSAndroid Build Coastguard Worker size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) override; 488*795d594fSAndroid Build Coastguard Worker size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) override; 489*795d594fSAndroid Build Coastguard Worker size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) override; 490*795d594fSAndroid Build Coastguard Worker size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) override; 491*795d594fSAndroid Build Coastguard Worker 492*795d594fSAndroid Build Coastguard Worker void DumpCoreRegister(std::ostream& stream, int reg) const override; 493*795d594fSAndroid Build Coastguard Worker void DumpFloatingPointRegister(std::ostream& stream, int reg) const override; 494*795d594fSAndroid Build Coastguard Worker GetInstructionSet()495*795d594fSAndroid Build Coastguard Worker InstructionSet GetInstructionSet() const override { return InstructionSet::kRiscv64; } 496*795d594fSAndroid Build Coastguard Worker 497*795d594fSAndroid Build Coastguard Worker const Riscv64InstructionSetFeatures& GetInstructionSetFeatures() const; 498*795d594fSAndroid Build Coastguard Worker GetPreferredSlotsAlignment()499*795d594fSAndroid Build Coastguard Worker uint32_t GetPreferredSlotsAlignment() const override { 500*795d594fSAndroid Build Coastguard Worker return static_cast<uint32_t>(kRiscv64PointerSize); 501*795d594fSAndroid Build Coastguard Worker } 502*795d594fSAndroid Build Coastguard Worker 503*795d594fSAndroid Build Coastguard Worker void Finalize() override; 504*795d594fSAndroid Build Coastguard Worker 505*795d594fSAndroid Build Coastguard Worker // Generate code to invoke a runtime entry point. 506*795d594fSAndroid Build Coastguard Worker void InvokeRuntime(QuickEntrypointEnum entrypoint, 507*795d594fSAndroid Build Coastguard Worker HInstruction* instruction, 508*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 509*795d594fSAndroid Build Coastguard Worker SlowPathCode* slow_path = nullptr) override; 510*795d594fSAndroid Build Coastguard Worker 511*795d594fSAndroid Build Coastguard Worker // Generate code to invoke a runtime entry point, but do not record 512*795d594fSAndroid Build Coastguard Worker // PC-related information in a stack map. 513*795d594fSAndroid Build Coastguard Worker void InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset, 514*795d594fSAndroid Build Coastguard Worker HInstruction* instruction, 515*795d594fSAndroid Build Coastguard Worker SlowPathCode* slow_path); 516*795d594fSAndroid Build Coastguard Worker GetMoveResolver()517*795d594fSAndroid Build Coastguard Worker ParallelMoveResolver* GetMoveResolver() override { return &move_resolver_; } 518*795d594fSAndroid Build Coastguard Worker NeedsTwoRegisters(DataType::Type type)519*795d594fSAndroid Build Coastguard Worker bool NeedsTwoRegisters([[maybe_unused]] DataType::Type type) const override { return false; } 520*795d594fSAndroid Build Coastguard Worker 521*795d594fSAndroid Build Coastguard Worker void IncreaseFrame(size_t adjustment) override; 522*795d594fSAndroid Build Coastguard Worker void DecreaseFrame(size_t adjustment) override; 523*795d594fSAndroid Build Coastguard Worker 524*795d594fSAndroid Build Coastguard Worker void GenerateNop() override; 525*795d594fSAndroid Build Coastguard Worker 526*795d594fSAndroid Build Coastguard Worker void GenerateImplicitNullCheck(HNullCheck* instruction) override; 527*795d594fSAndroid Build Coastguard Worker void GenerateExplicitNullCheck(HNullCheck* instruction) override; 528*795d594fSAndroid Build Coastguard Worker 529*795d594fSAndroid Build Coastguard Worker // Check if the desired_string_load_kind is supported. If it is, return it, 530*795d594fSAndroid Build Coastguard Worker // otherwise return a fall-back kind that should be used instead. 531*795d594fSAndroid Build Coastguard Worker HLoadString::LoadKind GetSupportedLoadStringKind( 532*795d594fSAndroid Build Coastguard Worker HLoadString::LoadKind desired_string_load_kind) override; 533*795d594fSAndroid Build Coastguard Worker 534*795d594fSAndroid Build Coastguard Worker // Check if the desired_class_load_kind is supported. If it is, return it, 535*795d594fSAndroid Build Coastguard Worker // otherwise return a fall-back kind that should be used instead. 536*795d594fSAndroid Build Coastguard Worker HLoadClass::LoadKind GetSupportedLoadClassKind( 537*795d594fSAndroid Build Coastguard Worker HLoadClass::LoadKind desired_class_load_kind) override; 538*795d594fSAndroid Build Coastguard Worker 539*795d594fSAndroid Build Coastguard Worker // Check if the desired_dispatch_info is supported. If it is, return it, 540*795d594fSAndroid Build Coastguard Worker // otherwise return a fall-back info that should be used instead. 541*795d594fSAndroid Build Coastguard Worker HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch( 542*795d594fSAndroid Build Coastguard Worker const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info, ArtMethod* method) override; 543*795d594fSAndroid Build Coastguard Worker 544*795d594fSAndroid Build Coastguard Worker // The PcRelativePatchInfo is used for PC-relative addressing of methods/strings/types, 545*795d594fSAndroid Build Coastguard Worker // whether through .data.img.rel.ro, .bss, or directly in the boot image. 546*795d594fSAndroid Build Coastguard Worker // 547*795d594fSAndroid Build Coastguard Worker // The 20-bit and 12-bit parts of the 32-bit PC-relative offset are patched separately, 548*795d594fSAndroid Build Coastguard Worker // necessitating two patches/infos. There can be more than two patches/infos if the 549*795d594fSAndroid Build Coastguard Worker // instruction supplying the high part is shared with e.g. a slow path, while the low 550*795d594fSAndroid Build Coastguard Worker // part is supplied by separate instructions, e.g.: 551*795d594fSAndroid Build Coastguard Worker // auipc r1, high // patch 552*795d594fSAndroid Build Coastguard Worker // lwu r2, low(r1) // patch 553*795d594fSAndroid Build Coastguard Worker // beqz r2, slow_path 554*795d594fSAndroid Build Coastguard Worker // back: 555*795d594fSAndroid Build Coastguard Worker // ... 556*795d594fSAndroid Build Coastguard Worker // slow_path: 557*795d594fSAndroid Build Coastguard Worker // ... 558*795d594fSAndroid Build Coastguard Worker // sw r2, low(r1) // patch 559*795d594fSAndroid Build Coastguard Worker // j back 560*795d594fSAndroid Build Coastguard Worker struct PcRelativePatchInfo : PatchInfo<Riscv64Label> { PcRelativePatchInfoPcRelativePatchInfo561*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo(const DexFile* dex_file, 562*795d594fSAndroid Build Coastguard Worker uint32_t off_or_idx, 563*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high) 564*795d594fSAndroid Build Coastguard Worker : PatchInfo<Riscv64Label>(dex_file, off_or_idx), 565*795d594fSAndroid Build Coastguard Worker pc_insn_label(info_high != nullptr ? &info_high->label : &label) { 566*795d594fSAndroid Build Coastguard Worker DCHECK_IMPLIES(info_high != nullptr, info_high->pc_insn_label == &info_high->label); 567*795d594fSAndroid Build Coastguard Worker } 568*795d594fSAndroid Build Coastguard Worker 569*795d594fSAndroid Build Coastguard Worker // Pointer to the info for the high part patch or nullptr if this is the high part patch info. 570*795d594fSAndroid Build Coastguard Worker const Riscv64Label* pc_insn_label; 571*795d594fSAndroid Build Coastguard Worker 572*795d594fSAndroid Build Coastguard Worker private: 573*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo(PcRelativePatchInfo&& other) = delete; 574*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(PcRelativePatchInfo); 575*795d594fSAndroid Build Coastguard Worker }; 576*795d594fSAndroid Build Coastguard Worker 577*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewBootImageIntrinsicPatch(uint32_t intrinsic_data, 578*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 579*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewBootImageRelRoPatch(uint32_t boot_image_offset, 580*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 581*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewAppImageMethodPatch(MethodReference target_method, 582*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 583*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewBootImageMethodPatch(MethodReference target_method, 584*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 585*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewMethodBssEntryPatch(MethodReference target_method, 586*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 587*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewBootImageJniEntrypointPatch( 588*795d594fSAndroid Build Coastguard Worker MethodReference target_method, const PcRelativePatchInfo* info_high = nullptr); 589*795d594fSAndroid Build Coastguard Worker 590*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewBootImageTypePatch(const DexFile& dex_file, 591*795d594fSAndroid Build Coastguard Worker dex::TypeIndex type_index, 592*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 593*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewAppImageTypePatch(const DexFile& dex_file, 594*795d594fSAndroid Build Coastguard Worker dex::TypeIndex type_index, 595*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 596*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewTypeBssEntryPatch(HLoadClass* load_class, 597*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 598*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewBootImageStringPatch(const DexFile& dex_file, 599*795d594fSAndroid Build Coastguard Worker dex::StringIndex string_index, 600*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 601*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewStringBssEntryPatch(const DexFile& dex_file, 602*795d594fSAndroid Build Coastguard Worker dex::StringIndex string_index, 603*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high = nullptr); 604*795d594fSAndroid Build Coastguard Worker 605*795d594fSAndroid Build Coastguard Worker void EmitPcRelativeAuipcPlaceholder(PcRelativePatchInfo* info_high, XRegister out); 606*795d594fSAndroid Build Coastguard Worker void EmitPcRelativeAddiPlaceholder(PcRelativePatchInfo* info_low, XRegister rd, XRegister rs1); 607*795d594fSAndroid Build Coastguard Worker void EmitPcRelativeLwuPlaceholder(PcRelativePatchInfo* info_low, XRegister rd, XRegister rs1); 608*795d594fSAndroid Build Coastguard Worker void EmitPcRelativeLdPlaceholder(PcRelativePatchInfo* info_low, XRegister rd, XRegister rs1); 609*795d594fSAndroid Build Coastguard Worker 610*795d594fSAndroid Build Coastguard Worker void EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linker_patches) override; 611*795d594fSAndroid Build Coastguard Worker 612*795d594fSAndroid Build Coastguard Worker Literal* DeduplicateBootImageAddressLiteral(uint64_t address); 613*795d594fSAndroid Build Coastguard Worker void PatchJitRootUse(uint8_t* code, 614*795d594fSAndroid Build Coastguard Worker const uint8_t* roots_data, 615*795d594fSAndroid Build Coastguard Worker const Literal* literal, 616*795d594fSAndroid Build Coastguard Worker uint64_t index_in_table) const; 617*795d594fSAndroid Build Coastguard Worker Literal* DeduplicateJitStringLiteral(const DexFile& dex_file, 618*795d594fSAndroid Build Coastguard Worker dex::StringIndex string_index, 619*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> handle); 620*795d594fSAndroid Build Coastguard Worker Literal* DeduplicateJitClassLiteral(const DexFile& dex_file, 621*795d594fSAndroid Build Coastguard Worker dex::TypeIndex type_index, 622*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> handle); 623*795d594fSAndroid Build Coastguard Worker void EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) override; 624*795d594fSAndroid Build Coastguard Worker 625*795d594fSAndroid Build Coastguard Worker void LoadTypeForBootImageIntrinsic(XRegister dest, TypeReference target_type); 626*795d594fSAndroid Build Coastguard Worker void LoadBootImageRelRoEntry(XRegister dest, uint32_t boot_image_offset); 627*795d594fSAndroid Build Coastguard Worker void LoadBootImageAddress(XRegister dest, uint32_t boot_image_reference); 628*795d594fSAndroid Build Coastguard Worker void LoadIntrinsicDeclaringClass(XRegister dest, HInvoke* invoke); 629*795d594fSAndroid Build Coastguard Worker void LoadClassRootForIntrinsic(XRegister dest, ClassRoot class_root); 630*795d594fSAndroid Build Coastguard Worker 631*795d594fSAndroid Build Coastguard Worker void LoadMethod(MethodLoadKind load_kind, Location temp, HInvoke* invoke); 632*795d594fSAndroid Build Coastguard Worker void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, 633*795d594fSAndroid Build Coastguard Worker Location temp, 634*795d594fSAndroid Build Coastguard Worker SlowPathCode* slow_path = nullptr) override; 635*795d594fSAndroid Build Coastguard Worker void GenerateVirtualCall(HInvokeVirtual* invoke, 636*795d594fSAndroid Build Coastguard Worker Location temp, 637*795d594fSAndroid Build Coastguard Worker SlowPathCode* slow_path = nullptr) override; 638*795d594fSAndroid Build Coastguard Worker void MoveFromReturnRegister(Location trg, DataType::Type type) override; 639*795d594fSAndroid Build Coastguard Worker 640*795d594fSAndroid Build Coastguard Worker void GenerateMemoryBarrier(MemBarrierKind kind); 641*795d594fSAndroid Build Coastguard Worker 642*795d594fSAndroid Build Coastguard Worker void MaybeIncrementHotness(HSuspendCheck* suspend_check, bool is_frame_entry); 643*795d594fSAndroid Build Coastguard Worker 644*795d594fSAndroid Build Coastguard Worker bool CanUseImplicitSuspendCheck() const; 645*795d594fSAndroid Build Coastguard Worker 646*795d594fSAndroid Build Coastguard Worker 647*795d594fSAndroid Build Coastguard Worker // Create slow path for a Baker read barrier for a GC root load within `instruction`. 648*795d594fSAndroid Build Coastguard Worker SlowPathCodeRISCV64* AddGcRootBakerBarrierBarrierSlowPath( 649*795d594fSAndroid Build Coastguard Worker HInstruction* instruction, Location root, Location temp); 650*795d594fSAndroid Build Coastguard Worker 651*795d594fSAndroid Build Coastguard Worker // Emit marking check for a Baker read barrier for a GC root load within `instruction`. 652*795d594fSAndroid Build Coastguard Worker void EmitBakerReadBarierMarkingCheck( 653*795d594fSAndroid Build Coastguard Worker SlowPathCodeRISCV64* slow_path, Location root, Location temp); 654*795d594fSAndroid Build Coastguard Worker 655*795d594fSAndroid Build Coastguard Worker // Generate a GC root reference load: 656*795d594fSAndroid Build Coastguard Worker // 657*795d594fSAndroid Build Coastguard Worker // root <- *(obj + offset) 658*795d594fSAndroid Build Coastguard Worker // 659*795d594fSAndroid Build Coastguard Worker // while honoring read barriers (if any). 660*795d594fSAndroid Build Coastguard Worker void GenerateGcRootFieldLoad(HInstruction* instruction, 661*795d594fSAndroid Build Coastguard Worker Location root, 662*795d594fSAndroid Build Coastguard Worker XRegister obj, 663*795d594fSAndroid Build Coastguard Worker uint32_t offset, 664*795d594fSAndroid Build Coastguard Worker ReadBarrierOption read_barrier_option, 665*795d594fSAndroid Build Coastguard Worker Riscv64Label* label_low = nullptr); 666*795d594fSAndroid Build Coastguard Worker 667*795d594fSAndroid Build Coastguard Worker // Fast path implementation of ReadBarrier::Barrier for a heap 668*795d594fSAndroid Build Coastguard Worker // reference field load when Baker's read barriers are used. 669*795d594fSAndroid Build Coastguard Worker void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction, 670*795d594fSAndroid Build Coastguard Worker Location ref, 671*795d594fSAndroid Build Coastguard Worker XRegister obj, 672*795d594fSAndroid Build Coastguard Worker uint32_t offset, 673*795d594fSAndroid Build Coastguard Worker Location temp, 674*795d594fSAndroid Build Coastguard Worker bool needs_null_check); 675*795d594fSAndroid Build Coastguard Worker // Fast path implementation of ReadBarrier::Barrier for a heap 676*795d594fSAndroid Build Coastguard Worker // reference array load when Baker's read barriers are used. 677*795d594fSAndroid Build Coastguard Worker void GenerateArrayLoadWithBakerReadBarrier(HInstruction* instruction, 678*795d594fSAndroid Build Coastguard Worker Location ref, 679*795d594fSAndroid Build Coastguard Worker XRegister obj, 680*795d594fSAndroid Build Coastguard Worker uint32_t data_offset, 681*795d594fSAndroid Build Coastguard Worker Location index, 682*795d594fSAndroid Build Coastguard Worker Location temp, 683*795d594fSAndroid Build Coastguard Worker bool needs_null_check); 684*795d594fSAndroid Build Coastguard Worker // Factored implementation, used by GenerateFieldLoadWithBakerReadBarrier, 685*795d594fSAndroid Build Coastguard Worker // GenerateArrayLoadWithBakerReadBarrier and intrinsics. 686*795d594fSAndroid Build Coastguard Worker void GenerateReferenceLoadWithBakerReadBarrier(HInstruction* instruction, 687*795d594fSAndroid Build Coastguard Worker Location ref, 688*795d594fSAndroid Build Coastguard Worker XRegister obj, 689*795d594fSAndroid Build Coastguard Worker uint32_t offset, 690*795d594fSAndroid Build Coastguard Worker Location index, 691*795d594fSAndroid Build Coastguard Worker Location temp, 692*795d594fSAndroid Build Coastguard Worker bool needs_null_check); 693*795d594fSAndroid Build Coastguard Worker 694*795d594fSAndroid Build Coastguard Worker // Create slow path for a read barrier for a heap reference within `instruction`. 695*795d594fSAndroid Build Coastguard Worker // 696*795d594fSAndroid Build Coastguard Worker // This is a helper function for GenerateReadBarrierSlow() that has the same 697*795d594fSAndroid Build Coastguard Worker // arguments. The creation and adding of the slow path is exposed for intrinsics 698*795d594fSAndroid Build Coastguard Worker // that cannot use GenerateReadBarrierSlow() from their own slow paths. 699*795d594fSAndroid Build Coastguard Worker SlowPathCodeRISCV64* AddReadBarrierSlowPath(HInstruction* instruction, 700*795d594fSAndroid Build Coastguard Worker Location out, 701*795d594fSAndroid Build Coastguard Worker Location ref, 702*795d594fSAndroid Build Coastguard Worker Location obj, 703*795d594fSAndroid Build Coastguard Worker uint32_t offset, 704*795d594fSAndroid Build Coastguard Worker Location index); 705*795d594fSAndroid Build Coastguard Worker 706*795d594fSAndroid Build Coastguard Worker // Generate a read barrier for a heap reference within `instruction` 707*795d594fSAndroid Build Coastguard Worker // using a slow path. 708*795d594fSAndroid Build Coastguard Worker // 709*795d594fSAndroid Build Coastguard Worker // A read barrier for an object reference read from the heap is 710*795d594fSAndroid Build Coastguard Worker // implemented as a call to the artReadBarrierSlow runtime entry 711*795d594fSAndroid Build Coastguard Worker // point, which is passed the values in locations `ref`, `obj`, and 712*795d594fSAndroid Build Coastguard Worker // `offset`: 713*795d594fSAndroid Build Coastguard Worker // 714*795d594fSAndroid Build Coastguard Worker // mirror::Object* artReadBarrierSlow(mirror::Object* ref, 715*795d594fSAndroid Build Coastguard Worker // mirror::Object* obj, 716*795d594fSAndroid Build Coastguard Worker // uint32_t offset); 717*795d594fSAndroid Build Coastguard Worker // 718*795d594fSAndroid Build Coastguard Worker // The `out` location contains the value returned by 719*795d594fSAndroid Build Coastguard Worker // artReadBarrierSlow. 720*795d594fSAndroid Build Coastguard Worker // 721*795d594fSAndroid Build Coastguard Worker // When `index` is provided (i.e. for array accesses), the offset 722*795d594fSAndroid Build Coastguard Worker // value passed to artReadBarrierSlow is adjusted to take `index` 723*795d594fSAndroid Build Coastguard Worker // into account. 724*795d594fSAndroid Build Coastguard Worker void GenerateReadBarrierSlow(HInstruction* instruction, 725*795d594fSAndroid Build Coastguard Worker Location out, 726*795d594fSAndroid Build Coastguard Worker Location ref, 727*795d594fSAndroid Build Coastguard Worker Location obj, 728*795d594fSAndroid Build Coastguard Worker uint32_t offset, 729*795d594fSAndroid Build Coastguard Worker Location index = Location::NoLocation()); 730*795d594fSAndroid Build Coastguard Worker 731*795d594fSAndroid Build Coastguard Worker // If read barriers are enabled, generate a read barrier for a heap 732*795d594fSAndroid Build Coastguard Worker // reference using a slow path. If heap poisoning is enabled, also 733*795d594fSAndroid Build Coastguard Worker // unpoison the reference in `out`. 734*795d594fSAndroid Build Coastguard Worker void MaybeGenerateReadBarrierSlow(HInstruction* instruction, 735*795d594fSAndroid Build Coastguard Worker Location out, 736*795d594fSAndroid Build Coastguard Worker Location ref, 737*795d594fSAndroid Build Coastguard Worker Location obj, 738*795d594fSAndroid Build Coastguard Worker uint32_t offset, 739*795d594fSAndroid Build Coastguard Worker Location index = Location::NoLocation()); 740*795d594fSAndroid Build Coastguard Worker 741*795d594fSAndroid Build Coastguard Worker // Generate a read barrier for a GC root within `instruction` using 742*795d594fSAndroid Build Coastguard Worker // a slow path. 743*795d594fSAndroid Build Coastguard Worker // 744*795d594fSAndroid Build Coastguard Worker // A read barrier for an object reference GC root is implemented as 745*795d594fSAndroid Build Coastguard Worker // a call to the artReadBarrierForRootSlow runtime entry point, 746*795d594fSAndroid Build Coastguard Worker // which is passed the value in location `root`: 747*795d594fSAndroid Build Coastguard Worker // 748*795d594fSAndroid Build Coastguard Worker // mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root); 749*795d594fSAndroid Build Coastguard Worker // 750*795d594fSAndroid Build Coastguard Worker // The `out` location contains the value returned by 751*795d594fSAndroid Build Coastguard Worker // artReadBarrierForRootSlow. 752*795d594fSAndroid Build Coastguard Worker void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root); 753*795d594fSAndroid Build Coastguard Worker 754*795d594fSAndroid Build Coastguard Worker // Emit a write barrier if: 755*795d594fSAndroid Build Coastguard Worker // A) emit_null_check is false 756*795d594fSAndroid Build Coastguard Worker // B) emit_null_check is true, and value is not null. 757*795d594fSAndroid Build Coastguard Worker void MaybeMarkGCCard(XRegister object, XRegister value, bool emit_null_check); 758*795d594fSAndroid Build Coastguard Worker 759*795d594fSAndroid Build Coastguard Worker // Emit a write barrier unconditionally. 760*795d594fSAndroid Build Coastguard Worker void MarkGCCard(XRegister object); 761*795d594fSAndroid Build Coastguard Worker 762*795d594fSAndroid Build Coastguard Worker // Crash if the card table is not valid. This check is only emitted for the CC GC. We assert 763*795d594fSAndroid Build Coastguard Worker // `(!clean || !self->is_gc_marking)`, since the card table should not be set to clean when the CC 764*795d594fSAndroid Build Coastguard Worker // GC is marking for eliminated write barriers. 765*795d594fSAndroid Build Coastguard Worker void CheckGCCardIsValid(XRegister object); 766*795d594fSAndroid Build Coastguard Worker 767*795d594fSAndroid Build Coastguard Worker // 768*795d594fSAndroid Build Coastguard Worker // Heap poisoning. 769*795d594fSAndroid Build Coastguard Worker // 770*795d594fSAndroid Build Coastguard Worker 771*795d594fSAndroid Build Coastguard Worker // Poison a heap reference contained in `reg`. 772*795d594fSAndroid Build Coastguard Worker void PoisonHeapReference(XRegister reg); 773*795d594fSAndroid Build Coastguard Worker 774*795d594fSAndroid Build Coastguard Worker // Unpoison a heap reference contained in `reg`. 775*795d594fSAndroid Build Coastguard Worker void UnpoisonHeapReference(XRegister reg); 776*795d594fSAndroid Build Coastguard Worker 777*795d594fSAndroid Build Coastguard Worker // Poison a heap reference contained in `reg` if heap poisoning is enabled. 778*795d594fSAndroid Build Coastguard Worker void MaybePoisonHeapReference(XRegister reg); 779*795d594fSAndroid Build Coastguard Worker 780*795d594fSAndroid Build Coastguard Worker // Unpoison a heap reference contained in `reg` if heap poisoning is enabled. 781*795d594fSAndroid Build Coastguard Worker void MaybeUnpoisonHeapReference(XRegister reg); 782*795d594fSAndroid Build Coastguard Worker 783*795d594fSAndroid Build Coastguard Worker void SwapLocations(Location loc1, Location loc2, DataType::Type type); 784*795d594fSAndroid Build Coastguard Worker 785*795d594fSAndroid Build Coastguard Worker private: 786*795d594fSAndroid Build Coastguard Worker using Uint32ToLiteralMap = ArenaSafeMap<uint32_t, Literal*>; 787*795d594fSAndroid Build Coastguard Worker using Uint64ToLiteralMap = ArenaSafeMap<uint64_t, Literal*>; 788*795d594fSAndroid Build Coastguard Worker using StringToLiteralMap = 789*795d594fSAndroid Build Coastguard Worker ArenaSafeMap<StringReference, Literal*, StringReferenceValueComparator>; 790*795d594fSAndroid Build Coastguard Worker using TypeToLiteralMap = ArenaSafeMap<TypeReference, Literal*, TypeReferenceValueComparator>; 791*795d594fSAndroid Build Coastguard Worker 792*795d594fSAndroid Build Coastguard Worker Literal* DeduplicateUint32Literal(uint32_t value); 793*795d594fSAndroid Build Coastguard Worker Literal* DeduplicateUint64Literal(uint64_t value); 794*795d594fSAndroid Build Coastguard Worker 795*795d594fSAndroid Build Coastguard Worker PcRelativePatchInfo* NewPcRelativePatch(const DexFile* dex_file, 796*795d594fSAndroid Build Coastguard Worker uint32_t offset_or_index, 797*795d594fSAndroid Build Coastguard Worker const PcRelativePatchInfo* info_high, 798*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo>* patches); 799*795d594fSAndroid Build Coastguard Worker 800*795d594fSAndroid Build Coastguard Worker template <linker::LinkerPatch (*Factory)(size_t, const DexFile*, uint32_t, uint32_t)> 801*795d594fSAndroid Build Coastguard Worker void EmitPcRelativeLinkerPatches(const ArenaDeque<PcRelativePatchInfo>& infos, 802*795d594fSAndroid Build Coastguard Worker ArenaVector<linker::LinkerPatch>* linker_patches); 803*795d594fSAndroid Build Coastguard Worker 804*795d594fSAndroid Build Coastguard Worker Riscv64Assembler assembler_; 805*795d594fSAndroid Build Coastguard Worker LocationsBuilderRISCV64 location_builder_; 806*795d594fSAndroid Build Coastguard Worker InstructionCodeGeneratorRISCV64 instruction_visitor_; 807*795d594fSAndroid Build Coastguard Worker Riscv64Label frame_entry_label_; 808*795d594fSAndroid Build Coastguard Worker 809*795d594fSAndroid Build Coastguard Worker // Labels for each block that will be compiled. 810*795d594fSAndroid Build Coastguard Worker Riscv64Label* block_labels_; // Indexed by block id. 811*795d594fSAndroid Build Coastguard Worker 812*795d594fSAndroid Build Coastguard Worker ParallelMoveResolverRISCV64 move_resolver_; 813*795d594fSAndroid Build Coastguard Worker 814*795d594fSAndroid Build Coastguard Worker // Deduplication map for 32-bit literals, used for non-patchable boot image addresses. 815*795d594fSAndroid Build Coastguard Worker Uint32ToLiteralMap uint32_literals_; 816*795d594fSAndroid Build Coastguard Worker // Deduplication map for 64-bit literals, used for non-patchable method address or method code 817*795d594fSAndroid Build Coastguard Worker // address. 818*795d594fSAndroid Build Coastguard Worker Uint64ToLiteralMap uint64_literals_; 819*795d594fSAndroid Build Coastguard Worker 820*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kBootImageLinkTimePcRelative. 821*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> boot_image_method_patches_; 822*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kAppImageRelRo. 823*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> app_image_method_patches_; 824*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kBssEntry. 825*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> method_bss_entry_patches_; 826*795d594fSAndroid Build Coastguard Worker // PC-relative type patch info for kBootImageLinkTimePcRelative. 827*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> boot_image_type_patches_; 828*795d594fSAndroid Build Coastguard Worker // PC-relative type patch info for kAppImageRelRo. 829*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> app_image_type_patches_; 830*795d594fSAndroid Build Coastguard Worker // PC-relative type patch info for kBssEntry. 831*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_; 832*795d594fSAndroid Build Coastguard Worker // PC-relative public type patch info for kBssEntryPublic. 833*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> public_type_bss_entry_patches_; 834*795d594fSAndroid Build Coastguard Worker // PC-relative package type patch info for kBssEntryPackage. 835*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> package_type_bss_entry_patches_; 836*795d594fSAndroid Build Coastguard Worker // PC-relative String patch info for kBootImageLinkTimePcRelative. 837*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> boot_image_string_patches_; 838*795d594fSAndroid Build Coastguard Worker // PC-relative String patch info for kBssEntry. 839*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> string_bss_entry_patches_; 840*795d594fSAndroid Build Coastguard Worker // PC-relative method patch info for kBootImageLinkTimePcRelative+kCallCriticalNative. 841*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> boot_image_jni_entrypoint_patches_; 842*795d594fSAndroid Build Coastguard Worker // PC-relative patch info for IntrinsicObjects for the boot image, 843*795d594fSAndroid Build Coastguard Worker // and for method/type/string patches for kBootImageRelRo otherwise. 844*795d594fSAndroid Build Coastguard Worker ArenaDeque<PcRelativePatchInfo> boot_image_other_patches_; 845*795d594fSAndroid Build Coastguard Worker 846*795d594fSAndroid Build Coastguard Worker // Patches for string root accesses in JIT compiled code. 847*795d594fSAndroid Build Coastguard Worker StringToLiteralMap jit_string_patches_; 848*795d594fSAndroid Build Coastguard Worker // Patches for class root accesses in JIT compiled code. 849*795d594fSAndroid Build Coastguard Worker TypeToLiteralMap jit_class_patches_; 850*795d594fSAndroid Build Coastguard Worker }; 851*795d594fSAndroid Build Coastguard Worker 852*795d594fSAndroid Build Coastguard Worker } // namespace riscv64 853*795d594fSAndroid Build Coastguard Worker } // namespace art 854*795d594fSAndroid Build Coastguard Worker 855*795d594fSAndroid Build Coastguard Worker #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_RISCV64_H_ 856