summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_arm.h
diff options
context:
space:
mode:
authorRoland Levillain <rpl@google.com>2017-07-14 14:34:22 +0100
committerRoland Levillain <rpl@google.com>2017-07-14 17:25:39 +0100
commit9983e302384c12a975c8d2d5ae239f79fd8e1996 (patch)
tree4e4d269fe1a3d4f0f1b93cd972adab9f17aab8e0 /compiler/optimizing/code_generator_arm.h
parentbac2bd1c2fbdd94f4d4dfe83d8451f655e875e36 (diff)
Remove the old ARM code generator from ART's Optimizing compiler.
The AArch32 VIXL-based code generator has been the default ARM code generator in ART for some time now. The old ARM code generator does not compile anymore; retiring it. Test: test.py Bug: 63316036 Change-Id: Iab8fbc4ac73eac2c1a809cd7b22fec6b619755db
Diffstat (limited to 'compiler/optimizing/code_generator_arm.h')
-rw-r--r--compiler/optimizing/code_generator_arm.h695
1 files changed, 0 insertions, 695 deletions
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
deleted file mode 100644
index 9280e6377c..0000000000
--- a/compiler/optimizing/code_generator_arm.h
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_
-#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_
-
-#include "base/enums.h"
-#include "code_generator.h"
-#include "dex_file_types.h"
-#include "driver/compiler_options.h"
-#include "nodes.h"
-#include "string_reference.h"
-#include "parallel_move_resolver.h"
-#include "type_reference.h"
-#include "utils/arm/assembler_thumb2.h"
-
-namespace art {
-namespace arm {
-
-class CodeGeneratorARM;
-
-// Use a local definition to prevent copying mistakes.
-static constexpr size_t kArmWordSize = static_cast<size_t>(kArmPointerSize);
-static constexpr size_t kArmBitsPerWord = kArmWordSize * kBitsPerByte;
-
-static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 };
-static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
-static constexpr SRegister kParameterFpuRegisters[] =
- { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15 };
-static constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters);
-
-static constexpr Register kArtMethodRegister = R0;
-
-static constexpr Register kRuntimeParameterCoreRegisters[] = { R0, R1, R2, R3 };
-static constexpr size_t kRuntimeParameterCoreRegistersLength =
- arraysize(kRuntimeParameterCoreRegisters);
-static constexpr SRegister kRuntimeParameterFpuRegisters[] = { S0, S1, S2, S3 };
-static constexpr size_t kRuntimeParameterFpuRegistersLength =
- arraysize(kRuntimeParameterFpuRegisters);
-
-class SlowPathCodeARM : public SlowPathCode {
- public:
- explicit SlowPathCodeARM(HInstruction* instruction) : SlowPathCode(instruction) {}
-
- void SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) FINAL;
- void RestoreLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) FINAL;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SlowPathCodeARM);
-};
-
-
-class InvokeRuntimeCallingConvention : public CallingConvention<Register, SRegister> {
- public:
- InvokeRuntimeCallingConvention()
- : CallingConvention(kRuntimeParameterCoreRegisters,
- kRuntimeParameterCoreRegistersLength,
- kRuntimeParameterFpuRegisters,
- kRuntimeParameterFpuRegistersLength,
- kArmPointerSize) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
-};
-
-constexpr DRegister FromLowSToD(SRegister reg) {
- DCHECK_EQ(reg % 2, 0);
- return static_cast<DRegister>(reg / 2);
-}
-
-
-class InvokeDexCallingConvention : public CallingConvention<Register, SRegister> {
- public:
- InvokeDexCallingConvention()
- : CallingConvention(kParameterCoreRegisters,
- kParameterCoreRegistersLength,
- kParameterFpuRegisters,
- kParameterFpuRegistersLength,
- kArmPointerSize) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
-};
-
-class InvokeDexCallingConventionVisitorARM : public InvokeDexCallingConventionVisitor {
- public:
- InvokeDexCallingConventionVisitorARM() {}
- virtual ~InvokeDexCallingConventionVisitorARM() {}
-
- Location GetNextLocation(Primitive::Type type) OVERRIDE;
- Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
- Location GetMethodLocation() const OVERRIDE;
-
- private:
- InvokeDexCallingConvention calling_convention;
- uint32_t double_index_ = 0;
-
- DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitorARM);
-};
-
-class FieldAccessCallingConventionARM : public FieldAccessCallingConvention {
- public:
- FieldAccessCallingConventionARM() {}
-
- Location GetObjectLocation() const OVERRIDE {
- return Location::RegisterLocation(R1);
- }
- Location GetFieldIndexLocation() const OVERRIDE {
- return Location::RegisterLocation(R0);
- }
- Location GetReturnLocation(Primitive::Type type) const OVERRIDE {
- return Primitive::Is64BitType(type)
- ? Location::RegisterPairLocation(R0, R1)
- : Location::RegisterLocation(R0);
- }
- Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE {
- return Primitive::Is64BitType(type)
- ? Location::RegisterPairLocation(R2, R3)
- : (is_instance
- ? Location::RegisterLocation(R2)
- : Location::RegisterLocation(R1));
- }
- Location GetFpuLocation(Primitive::Type type) const OVERRIDE {
- return Primitive::Is64BitType(type)
- ? Location::FpuRegisterPairLocation(S0, S1)
- : Location::FpuRegisterLocation(S0);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FieldAccessCallingConventionARM);
-};
-
-class ParallelMoveResolverARM : public ParallelMoveResolverWithSwap {
- public:
- ParallelMoveResolverARM(ArenaAllocator* allocator, CodeGeneratorARM* codegen)
- : ParallelMoveResolverWithSwap(allocator), codegen_(codegen) {}
-
- void EmitMove(size_t index) OVERRIDE;
- void EmitSwap(size_t index) OVERRIDE;
- void SpillScratch(int reg) OVERRIDE;
- void RestoreScratch(int reg) OVERRIDE;
-
- ArmAssembler* GetAssembler() const;
-
- private:
- void Exchange(Register reg, int mem);
- void Exchange(int mem1, int mem2);
-
- CodeGeneratorARM* const codegen_;
-
- DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolverARM);
-};
-
-class LocationsBuilderARM : public HGraphVisitor {
- public:
- LocationsBuilderARM(HGraph* graph, CodeGeneratorARM* codegen)
- : HGraphVisitor(graph), codegen_(codegen) {}
-
-#define DECLARE_VISIT_INSTRUCTION(name, super) \
- void Visit##name(H##name* instr) OVERRIDE;
-
- FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
- FOR_EACH_CONCRETE_INSTRUCTION_ARM(DECLARE_VISIT_INSTRUCTION)
- FOR_EACH_CONCRETE_INSTRUCTION_SHARED(DECLARE_VISIT_INSTRUCTION)
-
-#undef DECLARE_VISIT_INSTRUCTION
-
- void VisitInstruction(HInstruction* instruction) OVERRIDE {
- LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
- << " (id " << instruction->GetId() << ")";
- }
-
- private:
- void HandleInvoke(HInvoke* invoke);
- void HandleBitwiseOperation(HBinaryOperation* operation, Opcode opcode);
- void HandleCondition(HCondition* condition);
- void HandleIntegerRotate(LocationSummary* locations);
- void HandleLongRotate(LocationSummary* locations);
- void HandleShift(HBinaryOperation* operation);
- void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
- void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
-
- Location ArithmeticZeroOrFpuRegister(HInstruction* input);
- Location ArmEncodableConstantOrRegister(HInstruction* constant, Opcode opcode);
- bool CanEncodeConstantAsImmediate(HConstant* input_cst, Opcode opcode);
- bool CanEncodeConstantAsImmediate(uint32_t value, Opcode opcode, SetCc set_cc = kCcDontCare);
-
- CodeGeneratorARM* const codegen_;
- InvokeDexCallingConventionVisitorARM parameter_visitor_;
-
- DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM);
-};
-
-class InstructionCodeGeneratorARM : public InstructionCodeGenerator {
- public:
- InstructionCodeGeneratorARM(HGraph* graph, CodeGeneratorARM* codegen);
-
-#define DECLARE_VISIT_INSTRUCTION(name, super) \
- void Visit##name(H##name* instr) OVERRIDE;
-
- FOR_EACH_CONCRETE_INSTRUCTION_COMMON(DECLARE_VISIT_INSTRUCTION)
- FOR_EACH_CONCRETE_INSTRUCTION_ARM(DECLARE_VISIT_INSTRUCTION)
- FOR_EACH_CONCRETE_INSTRUCTION_SHARED(DECLARE_VISIT_INSTRUCTION)
-
-#undef DECLARE_VISIT_INSTRUCTION
-
- void VisitInstruction(HInstruction* instruction) OVERRIDE {
- LOG(FATAL) << "Unreachable instruction " << instruction->DebugName()
- << " (id " << instruction->GetId() << ")";
- }
-
- ArmAssembler* GetAssembler() const { return assembler_; }
-
- private:
- // Generate code for the given suspend check. If not null, `successor`
- // is the block to branch to if the suspend check is not needed, and after
- // the suspend call.
- void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
- void GenerateClassInitializationCheck(SlowPathCodeARM* slow_path, Register class_reg);
- void GenerateAndConst(Register out, Register first, uint32_t value);
- void GenerateOrrConst(Register out, Register first, uint32_t value);
- void GenerateEorConst(Register out, Register first, uint32_t value);
- void GenerateAddLongConst(Location out, Location first, uint64_t value);
- void HandleBitwiseOperation(HBinaryOperation* operation);
- void HandleCondition(HCondition* condition);
- void HandleIntegerRotate(LocationSummary* locations);
- void HandleLongRotate(HRor* ror);
- void HandleShift(HBinaryOperation* operation);
-
- void GenerateWideAtomicStore(Register addr, uint32_t offset,
- Register value_lo, Register value_hi,
- Register temp1, Register temp2,
- HInstruction* instruction);
- void GenerateWideAtomicLoad(Register addr, uint32_t offset,
- Register out_lo, Register out_hi);
-
- void HandleFieldSet(HInstruction* instruction,
- const FieldInfo& field_info,
- bool value_can_be_null);
- void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
-
- // Generate a heap reference load using one register `out`:
- //
- // out <- *(out + offset)
- //
- // while honoring heap poisoning and/or read barriers (if any).
- //
- // Location `maybe_temp` is used when generating a read barrier and
- // shall be a register in that case; it may be an invalid location
- // otherwise.
- void GenerateReferenceLoadOneRegister(HInstruction* instruction,
- Location out,
- uint32_t offset,
- Location maybe_temp,
- ReadBarrierOption read_barrier_option);
- // Generate a heap reference load using two different registers
- // `out` and `obj`:
- //
- // out <- *(obj + offset)
- //
- // while honoring heap poisoning and/or read barriers (if any).
- //
- // Location `maybe_temp` is used when generating a Baker's (fast
- // path) read barrier and shall be a register in that case; it may
- // be an invalid location otherwise.
- void GenerateReferenceLoadTwoRegisters(HInstruction* instruction,
- Location out,
- Location obj,
- uint32_t offset,
- Location maybe_temp,
- ReadBarrierOption read_barrier_option);
- // Generate a GC root reference load:
- //
- // root <- *(obj + offset)
- //
- // while honoring read barriers based on read_barrier_option.
- void GenerateGcRootFieldLoad(HInstruction* instruction,
- Location root,
- Register obj,
- uint32_t offset,
- ReadBarrierOption read_barrier_option);
- void GenerateTestAndBranch(HInstruction* instruction,
- size_t condition_input_index,
- Label* true_target,
- Label* false_target);
- void GenerateCompareTestAndBranch(HCondition* condition,
- Label* true_target,
- Label* false_target);
- void DivRemOneOrMinusOne(HBinaryOperation* instruction);
- void DivRemByPowerOfTwo(HBinaryOperation* instruction);
- void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
- void GenerateDivRemConstantIntegral(HBinaryOperation* instruction);
- void HandleGoto(HInstruction* got, HBasicBlock* successor);
-
- ArmAssembler* const assembler_;
- CodeGeneratorARM* const codegen_;
-
- DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM);
-};
-
-class CodeGeneratorARM : public CodeGenerator {
- public:
- CodeGeneratorARM(HGraph* graph,
- const ArmInstructionSetFeatures& isa_features,
- const CompilerOptions& compiler_options,
- OptimizingCompilerStats* stats = nullptr);
- virtual ~CodeGeneratorARM() {}
-
- void GenerateFrameEntry() OVERRIDE;
- void GenerateFrameExit() OVERRIDE;
- void Bind(HBasicBlock* block) OVERRIDE;
- void MoveConstant(Location destination, int32_t value) OVERRIDE;
- void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE;
- void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE;
-
- size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
- size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
- size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
- size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
-
- size_t GetWordSize() const OVERRIDE {
- return kArmWordSize;
- }
-
- size_t GetFloatingPointSpillSlotSize() const OVERRIDE {
- // Allocated in S registers, which are word sized.
- return kArmWordSize;
- }
-
- HGraphVisitor* GetLocationBuilder() OVERRIDE {
- return &location_builder_;
- }
-
- HGraphVisitor* GetInstructionVisitor() OVERRIDE {
- return &instruction_visitor_;
- }
-
- ArmAssembler* GetAssembler() OVERRIDE {
- return &assembler_;
- }
-
- const ArmAssembler& GetAssembler() const OVERRIDE {
- return assembler_;
- }
-
- uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
- return GetLabelOf(block)->Position();
- }
-
- void SetupBlockedRegisters() const OVERRIDE;
-
- void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
- void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
-
- ParallelMoveResolverARM* GetMoveResolver() OVERRIDE {
- return &move_resolver_;
- }
-
- InstructionSet GetInstructionSet() const OVERRIDE {
- return InstructionSet::kThumb2;
- }
-
- // Helper method to move a 32bits value between two locations.
- void Move32(Location destination, Location source);
- // Helper method to move a 64bits value between two locations.
- void Move64(Location destination, Location source);
-
- void LoadOrStoreToOffset(Primitive::Type type,
- Location loc,
- Register base,
- int32_t offset,
- bool is_load,
- Condition cond = AL);
-
- void LoadFromShiftedRegOffset(Primitive::Type type,
- Location out_loc,
- Register base,
- Register reg_offset,
- Condition cond = AL);
- void StoreToShiftedRegOffset(Primitive::Type type,
- Location out_loc,
- Register base,
- Register reg_offset,
- Condition cond = AL);
-
- // Generate code to invoke a runtime entry point.
- void InvokeRuntime(QuickEntrypointEnum entrypoint,
- HInstruction* instruction,
- uint32_t dex_pc,
- SlowPathCode* slow_path = nullptr) OVERRIDE;
-
- // Generate code to invoke a runtime entry point, but do not record
- // PC-related information in a stack map.
- void InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset,
- HInstruction* instruction,
- SlowPathCode* slow_path);
-
- void GenerateInvokeRuntime(int32_t entry_point_offset);
-
- // Emit a write barrier.
- void MarkGCCard(Register temp, Register card, Register object, Register value, bool can_be_null);
-
- void GenerateMemoryBarrier(MemBarrierKind kind);
-
- Label* GetLabelOf(HBasicBlock* block) const {
- return CommonGetLabelOf<Label>(block_labels_, block);
- }
-
- Label* GetFinalLabel(HInstruction* instruction, Label* final_label);
-
- void Initialize() OVERRIDE {
- block_labels_ = CommonInitializeLabels<Label>();
- }
-
- void Finalize(CodeAllocator* allocator) OVERRIDE;
-
- const ArmInstructionSetFeatures& GetInstructionSetFeatures() const {
- return isa_features_;
- }
-
- bool NeedsTwoRegisters(Primitive::Type type) const OVERRIDE {
- return type == Primitive::kPrimDouble || type == Primitive::kPrimLong;
- }
-
- void ComputeSpillMask() OVERRIDE;
-
- Label* GetFrameEntryLabel() { return &frame_entry_label_; }
-
- // Check if the desired_string_load_kind is supported. If it is, return it,
- // otherwise return a fall-back kind that should be used instead.
- HLoadString::LoadKind GetSupportedLoadStringKind(
- HLoadString::LoadKind desired_string_load_kind) OVERRIDE;
-
- // Check if the desired_class_load_kind is supported. If it is, return it,
- // otherwise return a fall-back kind that should be used instead.
- HLoadClass::LoadKind GetSupportedLoadClassKind(
- HLoadClass::LoadKind desired_class_load_kind) OVERRIDE;
-
- // Check if the desired_dispatch_info is supported. If it is, return it,
- // otherwise return a fall-back info that should be used instead.
- HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
- const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- HInvokeStaticOrDirect* invoke) OVERRIDE;
-
- void GenerateStaticOrDirectCall(
- HInvokeStaticOrDirect* invoke, Location temp, SlowPathCode* slow_path = nullptr) OVERRIDE;
- void GenerateVirtualCall(
- HInvokeVirtual* invoke, Location temp, SlowPathCode* slow_path = nullptr) OVERRIDE;
-
- void MoveFromReturnRegister(Location trg, Primitive::Type type) OVERRIDE;
-
- // The PcRelativePatchInfo is used for PC-relative addressing of dex cache arrays
- // and boot image strings/types. The only difference is the interpretation of the
- // offset_or_index. The PC-relative address is loaded with three instructions,
- // MOVW+MOVT to load the offset to base_reg and then ADD base_reg, PC. The offset
- // is calculated from the ADD's effective PC, i.e. PC+4 on Thumb2. Though we
- // currently emit these 3 instructions together, instruction scheduling could
- // split this sequence apart, so we keep separate labels for each of them.
- struct PcRelativePatchInfo {
- PcRelativePatchInfo(const DexFile& dex_file, uint32_t off_or_idx)
- : target_dex_file(dex_file), offset_or_index(off_or_idx) { }
- PcRelativePatchInfo(PcRelativePatchInfo&& other) = default;
-
- const DexFile& target_dex_file;
- // Either the dex cache array element offset or the string/type index.
- uint32_t offset_or_index;
- Label movw_label;
- Label movt_label;
- Label add_pc_label;
- };
-
- PcRelativePatchInfo* NewPcRelativeMethodPatch(MethodReference target_method);
- PcRelativePatchInfo* NewMethodBssEntryPatch(MethodReference target_method);
- PcRelativePatchInfo* NewPcRelativeTypePatch(const DexFile& dex_file, dex::TypeIndex type_index);
- PcRelativePatchInfo* NewTypeBssEntryPatch(const DexFile& dex_file, dex::TypeIndex type_index);
- PcRelativePatchInfo* NewPcRelativeStringPatch(const DexFile& dex_file,
- dex::StringIndex string_index);
-
- // Add a new baker read barrier patch and return the label to be bound
- // before the BNE instruction.
- Label* NewBakerReadBarrierPatch(uint32_t custom_data);
-
- Literal* DeduplicateBootImageAddressLiteral(uint32_t address);
- Literal* DeduplicateJitStringLiteral(const DexFile& dex_file,
- dex::StringIndex string_index,
- Handle<mirror::String> handle);
- Literal* DeduplicateJitClassLiteral(const DexFile& dex_file,
- dex::TypeIndex type_index,
- Handle<mirror::Class> handle);
-
- void EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patches) OVERRIDE;
-
- void EmitJitRootPatches(uint8_t* code, const uint8_t* roots_data) OVERRIDE;
-
- // Maybe add the reserved entrypoint register as a temporary for field load. This temp
- // is added only for AOT compilation if link-time generated thunks for fields are enabled.
- void MaybeAddBakerCcEntrypointTempForFields(LocationSummary* locations);
-
- // Fast path implementation of ReadBarrier::Barrier for a heap
- // reference field load when Baker's read barriers are used.
- void GenerateFieldLoadWithBakerReadBarrier(HInstruction* instruction,
- Location ref,
- Register obj,
- uint32_t offset,
- Location temp,
- bool needs_null_check);
- // Fast path implementation of ReadBarrier::Barrier for a heap
- // reference array load when Baker's read barriers are used.
- void GenerateArrayLoadWithBakerReadBarrier(HInstruction* instruction,
- Location ref,
- Register obj,
- uint32_t data_offset,
- Location index,
- Location temp,
- bool needs_null_check);
- // Factored implementation, used by GenerateFieldLoadWithBakerReadBarrier,
- // GenerateArrayLoadWithBakerReadBarrier and some intrinsics.
- //
- // Load the object reference located at the address
- // `obj + offset + (index << scale_factor)`, held by object `obj`, into
- // `ref`, and mark it if needed.
- void GenerateReferenceLoadWithBakerReadBarrier(HInstruction* instruction,
- Location ref,
- Register obj,
- uint32_t offset,
- Location index,
- ScaleFactor scale_factor,
- Location temp,
- bool needs_null_check);
-
- // Generate code checking whether the the reference field at the
- // address `obj + field_offset`, held by object `obj`, needs to be
- // marked, and if so, marking it and updating the field within `obj`
- // with the marked value.
- //
- // This routine is used for the implementation of the
- // UnsafeCASObject intrinsic with Baker read barriers.
- //
- // This method has a structure similar to
- // GenerateReferenceLoadWithBakerReadBarrier, but note that argument
- // `ref` is only as a temporary here, and thus its value should not
- // be used afterwards.
- void UpdateReferenceFieldWithBakerReadBarrier(HInstruction* instruction,
- Location ref,
- Register obj,
- Location field_offset,
- Location temp,
- bool needs_null_check,
- Register temp2);
-
- // Generate a heap reference load (with no read barrier).
- void GenerateRawReferenceLoad(HInstruction* instruction,
- Location ref,
- Register obj,
- uint32_t offset,
- Location index,
- ScaleFactor scale_factor,
- bool needs_null_check);
-
- // Generate a read barrier for a heap reference within `instruction`
- // using a slow path.
- //
- // A read barrier for an object reference read from the heap is
- // implemented as a call to the artReadBarrierSlow runtime entry
- // point, which is passed the values in locations `ref`, `obj`, and
- // `offset`:
- //
- // mirror::Object* artReadBarrierSlow(mirror::Object* ref,
- // mirror::Object* obj,
- // uint32_t offset);
- //
- // The `out` location contains the value returned by
- // artReadBarrierSlow.
- //
- // When `index` is provided (i.e. for array accesses), the offset
- // value passed to artReadBarrierSlow is adjusted to take `index`
- // into account.
- void GenerateReadBarrierSlow(HInstruction* instruction,
- Location out,
- Location ref,
- Location obj,
- uint32_t offset,
- Location index = Location::NoLocation());
-
- // If read barriers are enabled, generate a read barrier for a heap
- // reference using a slow path. If heap poisoning is enabled, also
- // unpoison the reference in `out`.
- void MaybeGenerateReadBarrierSlow(HInstruction* instruction,
- Location out,
- Location ref,
- Location obj,
- uint32_t offset,
- Location index = Location::NoLocation());
-
- // Generate a read barrier for a GC root within `instruction` using
- // a slow path.
- //
- // A read barrier for an object reference GC root is implemented as
- // a call to the artReadBarrierForRootSlow runtime entry point,
- // which is passed the value in location `root`:
- //
- // mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root);
- //
- // The `out` location contains the value returned by
- // artReadBarrierForRootSlow.
- void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root);
-
- void GenerateNop() OVERRIDE;
-
- void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
- void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
-
- // `temp` is an extra temporary register that is used for some conditions;
- // callers may not specify it, in which case the method will use a scratch
- // register instead.
- void GenerateConditionWithZero(IfCondition condition,
- Register out,
- Register in,
- Register temp = kNoRegister);
-
- private:
- Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp);
-
- using Uint32ToLiteralMap = ArenaSafeMap<uint32_t, Literal*>;
- using StringToLiteralMap = ArenaSafeMap<StringReference,
- Literal*,
- StringReferenceValueComparator>;
- using TypeToLiteralMap = ArenaSafeMap<TypeReference,
- Literal*,
- TypeReferenceValueComparator>;
-
- struct BakerReadBarrierPatchInfo {
- explicit BakerReadBarrierPatchInfo(uint32_t data) : label(), custom_data(data) { }
-
- Label label;
- uint32_t custom_data;
- };
-
- Literal* DeduplicateUint32Literal(uint32_t value, Uint32ToLiteralMap* map);
- PcRelativePatchInfo* NewPcRelativePatch(const DexFile& dex_file,
- uint32_t offset_or_index,
- ArenaDeque<PcRelativePatchInfo>* patches);
- template <LinkerPatch (*Factory)(size_t, const DexFile*, uint32_t, uint32_t)>
- static void EmitPcRelativeLinkerPatches(const ArenaDeque<PcRelativePatchInfo>& infos,
- ArenaVector<LinkerPatch>* linker_patches);
-
- // Labels for each block that will be compiled.
- Label* block_labels_; // Indexed by block id.
- Label frame_entry_label_;
- LocationsBuilderARM location_builder_;
- InstructionCodeGeneratorARM instruction_visitor_;
- ParallelMoveResolverARM move_resolver_;
- Thumb2Assembler assembler_;
- const ArmInstructionSetFeatures& isa_features_;
-
- // Deduplication map for 32-bit literals, used for non-patchable boot image addresses.
- Uint32ToLiteralMap uint32_literals_;
- // PC-relative method patch info for kBootImageLinkTimePcRelative.
- ArenaDeque<PcRelativePatchInfo> pc_relative_method_patches_;
- // PC-relative method patch info for kBssEntry.
- ArenaDeque<PcRelativePatchInfo> method_bss_entry_patches_;
- // PC-relative type patch info for kBootImageLinkTimePcRelative.
- ArenaDeque<PcRelativePatchInfo> pc_relative_type_patches_;
- // PC-relative type patch info for kBssEntry.
- ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
- // PC-relative String patch info; type depends on configuration (app .bss or boot image PIC).
- ArenaDeque<PcRelativePatchInfo> pc_relative_string_patches_;
- // Baker read barrier patch info.
- ArenaDeque<BakerReadBarrierPatchInfo> baker_read_barrier_patches_;
-
- // Patches for string literals in JIT compiled code.
- StringToLiteralMap jit_string_patches_;
- // Patches for class literals in JIT compiled code.
- TypeToLiteralMap jit_class_patches_;
-
- DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM);
-};
-
-} // namespace arm
-} // namespace art
-
-#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM_H_