diff options
Diffstat (limited to 'compiler/dex/quick/arm')
-rw-r--r-- | compiler/dex/quick/arm/assemble_arm.cc | 42 | ||||
-rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 30 | ||||
-rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 3 | ||||
-rw-r--r-- | compiler/dex/quick/arm/target_arm.cc | 42 | ||||
-rw-r--r-- | compiler/dex/quick/arm/utility_arm.cc | 19 |
5 files changed, 107 insertions, 29 deletions
diff --git a/compiler/dex/quick/arm/assemble_arm.cc b/compiler/dex/quick/arm/assemble_arm.cc index df4a9f2048..57ebca67e8 100644 --- a/compiler/dex/quick/arm/assemble_arm.cc +++ b/compiler/dex/quick/arm/assemble_arm.cc @@ -1082,6 +1082,19 @@ void ArmMir2Lir::InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir) { */ #define PADDING_MOV_R5_R5 0x1C2D +uint32_t ArmMir2Lir::ProcessMoreEncodings(const ArmEncodingMap* encoder, int i, uint32_t operand) { + LOG(FATAL) << "Bad fmt:" << encoder->field_loc[i].kind << " " << operand; + uint32_t value=0; + return value; +} + +const ArmEncodingMap * ArmMir2Lir::GetEncoder(int opcode) { + if (opcode < 0 || opcode >= kArmLast) + LOG(FATAL) << "invalid opcode " << opcode; + const ArmEncodingMap *encoder = &EncodingMap[opcode]; + return encoder; +} + uint8_t* ArmMir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { uint8_t* const write_buffer = write_pos; for (; lir != nullptr; lir = NEXT_LIR(lir)) { @@ -1098,7 +1111,7 @@ uint8_t* ArmMir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { } } } else if (LIKELY(!lir->flags.is_nop)) { - const ArmEncodingMap *encoder = &EncodingMap[lir->opcode]; + const ArmEncodingMap *encoder = GetEncoder(lir->opcode); uint32_t bits = encoder->skeleton; for (int i = 0; i < 4; i++) { uint32_t operand; @@ -1214,7 +1227,8 @@ uint8_t* ArmMir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { } break; default: - LOG(FATAL) << "Bad fmt:" << encoder->field_loc[i].kind; + bits |= ProcessMoreEncodings(encoder, i, operand); + break; } } } @@ -1324,7 +1338,7 @@ void ArmMir2Lir::AssembleLIR() { base_reg, 0, 0, 0, 0, lir->target); new_adr->offset = lir->offset; new_adr->flags.fixup = kFixupAdr; - new_adr->flags.size = EncodingMap[kThumb2Adr].size; + new_adr->flags.size = GetEncoder(kThumb2Adr)->size; InsertLIRBefore(lir, new_adr); lir->offset += new_adr->flags.size; offset_adjustment += new_adr->flags.size; @@ -1339,7 +1353,7 @@ void ArmMir2Lir::AssembleLIR() { } else if (lir->opcode == kThumb2LdrdPcRel8) { lir->opcode = kThumb2LdrdI8; } - lir->flags.size = EncodingMap[lir->opcode].size; + lir->flags.size = GetEncoder(lir->opcode)->size; offset_adjustment += lir->flags.size; // Change the load to be relative to the new Adr base. if (lir->opcode == kThumb2LdrdI8) { @@ -1389,13 +1403,13 @@ void ArmMir2Lir::AssembleLIR() { /* operand[0] is src1 in both cb[n]z & CmpRI8 */ lir->operands[1] = 0; lir->target = 0; - lir->flags.size = EncodingMap[lir->opcode].size; + lir->flags.size = GetEncoder(lir->opcode)->size; // Add back the new size. offset_adjustment += lir->flags.size; // Set up the new following inst. new_inst->offset = lir->offset + lir->flags.size; new_inst->flags.fixup = kFixupCondBranch; - new_inst->flags.size = EncodingMap[new_inst->opcode].size; + new_inst->flags.size = GetEncoder(new_inst->opcode)->size; offset_adjustment += new_inst->flags.size; // lir no longer pcrel, unlink and link in new_inst. @@ -1420,7 +1434,7 @@ void ArmMir2Lir::AssembleLIR() { if ((lir->opcode == kThumbBCond) && (delta > 254 || delta < -256)) { offset_adjustment -= lir->flags.size; lir->opcode = kThumb2BCond; - lir->flags.size = EncodingMap[lir->opcode].size; + lir->flags.size = GetEncoder(lir->opcode)->size; // Fixup kind remains the same. offset_adjustment += lir->flags.size; res = kRetryAll; @@ -1456,7 +1470,7 @@ void ArmMir2Lir::AssembleLIR() { offset_adjustment -= lir->flags.size; lir->opcode = kThumb2BUncond; lir->operands[0] = 0; - lir->flags.size = EncodingMap[lir->opcode].size; + lir->flags.size = GetEncoder(lir->opcode)->size; lir->flags.fixup = kFixupT2Branch; offset_adjustment += lir->flags.size; res = kRetryAll; @@ -1518,7 +1532,7 @@ void ArmMir2Lir::AssembleLIR() { LIR *new_mov16L = RawLIR(lir->dalvik_offset, kThumb2MovImm16LST, lir->operands[0], 0, WrapPointer(lir), WrapPointer(tab_rec), 0, lir->target); - new_mov16L->flags.size = EncodingMap[new_mov16L->opcode].size; + new_mov16L->flags.size = GetEncoder(new_mov16L->opcode)->size; new_mov16L->flags.fixup = kFixupMovImmLST; new_mov16L->offset = lir->offset; // Link the new instruction, retaining lir. @@ -1530,7 +1544,7 @@ void ArmMir2Lir::AssembleLIR() { LIR *new_mov16H = RawLIR(lir->dalvik_offset, kThumb2MovImm16HST, lir->operands[0], 0, WrapPointer(lir), WrapPointer(tab_rec), 0, lir->target); - new_mov16H->flags.size = EncodingMap[new_mov16H->opcode].size; + new_mov16H->flags.size = GetEncoder(new_mov16H->opcode)->size; new_mov16H->flags.fixup = kFixupMovImmHST; new_mov16H->offset = lir->offset; // Link the new instruction, retaining lir. @@ -1547,7 +1561,7 @@ void ArmMir2Lir::AssembleLIR() { lir->opcode = kThumbAddRRHH; } lir->operands[1] = rs_rARM_PC.GetReg(); - lir->flags.size = EncodingMap[lir->opcode].size; + lir->flags.size = GetEncoder(lir->opcode)->size; offset_adjustment += lir->flags.size; // Must stay in fixup list and have offset updated; will be used by LST/HSP pair. lir->flags.fixup = kFixupNone; @@ -1635,7 +1649,7 @@ void ArmMir2Lir::AssembleLIR() { size_t ArmMir2Lir::GetInsnSize(LIR* lir) { DCHECK(!IsPseudoLirOp(lir->opcode)); - return EncodingMap[lir->opcode].size; + return GetEncoder(lir->opcode)->size; } // Encode instruction bit pattern and assign offsets. @@ -1647,8 +1661,8 @@ uint32_t ArmMir2Lir::LinkFixupInsns(LIR* head_lir, LIR* tail_lir, uint32_t offse if (!lir->flags.is_nop) { if (lir->flags.fixup != kFixupNone) { if (!IsPseudoLirOp(lir->opcode)) { - lir->flags.size = EncodingMap[lir->opcode].size; - lir->flags.fixup = EncodingMap[lir->opcode].fixup; + lir->flags.size = GetEncoder(lir->opcode)->size; + lir->flags.fixup = GetEncoder(lir->opcode)->fixup; } else if (UNLIKELY(lir->opcode == kPseudoPseudoAlign4)) { lir->flags.size = (offset & 0x2); lir->flags.fixup = kFixupAlign4; diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index b94e707354..2fee96ddb8 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -22,10 +22,18 @@ #include "base/logging.h" #include "dex/quick/mir_to_lir.h" +#ifdef QC_STRONG +#define QC_WEAK +#else +#define QC_WEAK __attribute__((weak)) +#endif + namespace art { struct CompilationUnit; +class QCArmMir2Lir; + class ArmMir2Lir FINAL : public Mir2Lir { protected: // Inherited class for ARM backend. @@ -57,6 +65,7 @@ class ArmMir2Lir FINAL : public Mir2Lir { public: ArmMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); + ~ArmMir2Lir(); // Required for target - codegen helpers. bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, @@ -206,6 +215,7 @@ class ArmMir2Lir FINAL : public Mir2Lir { LIR* OpMem(OpKind op, RegStorage r_base, int disp); void OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); + LIR* OpBkpt(); void OpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src); LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value); @@ -271,12 +281,15 @@ class ArmMir2Lir FINAL : public Mir2Lir { LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) OVERRIDE; size_t GetInstructionOffset(LIR* lir); + void GenMoreMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) QC_WEAK; + //void MachineSpecificPreprocessMIR(BasicBlock* bb, MIR* mir); void GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) OVERRIDE; bool HandleEasyDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE; + void CleanupCodeGenData() QC_WEAK; private: void GenNegLong(RegLocation rl_dest, RegLocation rl_src); void GenMulLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, @@ -301,6 +314,12 @@ class ArmMir2Lir FINAL : public Mir2Lir { bool GetEasyMultiplyTwoOps(int lit, EasyMultiplyOp* ops); void GenEasyMultiplyTwoOps(RegStorage r_dest, RegStorage r_src, EasyMultiplyOp* ops); + + + static uint32_t ProcessMoreEncodings(const ArmEncodingMap* encoder, int i, uint32_t operand) QC_WEAK; + + static const ArmEncodingMap * GetEncoder(int opcode) QC_WEAK; + static constexpr ResourceMask GetRegMaskArm(RegStorage reg); static constexpr ResourceMask EncodeArmRegList(int reg_list); static constexpr ResourceMask EncodeArmRegFpcsList(int reg_list); @@ -351,6 +370,17 @@ class ArmMir2Lir FINAL : public Mir2Lir { InvokeType type); void OpPcRelDexCacheArrayAddr(const DexFile* dex_file, int offset, RegStorage r_dest); + + virtual void ApplyArchOptimizations(LIR* head_lir, LIR* tail_lir, BasicBlock* bb) QC_WEAK; + + void CompilerPostInitializeRegAlloc() QC_WEAK; + void ArmMir2LirPostInit(ArmMir2Lir* mir_to_lir) QC_WEAK; + + friend class QCArmMir2Lir; + + public: + QCArmMir2Lir * qcm2l ; + }; } // namespace art diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index cf0188456d..4ddf616724 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -754,8 +754,7 @@ RegLocation ArmMir2Lir::GenDivRem(RegLocation rl_dest, RegStorage reg1, RegStora RegStorage temp = AllocTemp(); OpRegRegReg(kOpDiv, temp, reg1, reg2); - OpRegReg(kOpMul, temp, reg2); - OpRegRegReg(kOpSub, rl_result.reg, reg1, temp); + NewLIR4(kThumb2Mls, rl_result.reg.GetReg(), temp.GetReg(), reg2.GetReg(), reg1.GetReg()); FreeTemp(temp); } diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc index 5f27338e6b..6702f79a33 100644 --- a/compiler/dex/quick/arm/target_arm.cc +++ b/compiler/dex/quick/arm/target_arm.cc @@ -140,11 +140,18 @@ ResourceMask ArmMir2Lir::GetRegMaskCommon(const RegStorage& reg) const { return GetRegMaskArm(reg); } +void ArmMir2Lir::CompilerPostInitializeRegAlloc() +{ + //nothing here +} + constexpr ResourceMask ArmMir2Lir::GetRegMaskArm(RegStorage reg) { - return reg.IsDouble() + return (reg.IsQuad()) + ? (ResourceMask::FourBits((reg.GetRegNum() * 4) + kArmFPReg0)) + : (reg.IsDouble() /* Each double register is equal to a pair of single-precision FP registers */ ? ResourceMask::TwoBits(reg.GetRegNum() * 2 + kArmFPReg0) - : ResourceMask::Bit(reg.IsSingle() ? reg.GetRegNum() + kArmFPReg0 : reg.GetRegNum()); + : ResourceMask::Bit(reg.IsSingle() ? reg.GetRegNum() + kArmFPReg0 : reg.GetRegNum())); } constexpr ResourceMask ArmMir2Lir::EncodeArmRegList(int reg_list) { @@ -586,6 +593,20 @@ ArmMir2Lir::ArmMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* << " is wrong: expecting " << i << ", seeing " << static_cast<int>(ArmMir2Lir::EncodingMap[i].opcode); } + qcm2l = nullptr; + ArmMir2LirPostInit(this); +} + +ArmMir2Lir::~ArmMir2Lir() +{ + CleanupCodeGenData(); +} + +void ArmMir2Lir::CleanupCodeGenData() +{ +} + +void ArmMir2Lir::ArmMir2LirPostInit(ArmMir2Lir*) { } Mir2Lir* ArmCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, @@ -633,6 +654,8 @@ void ArmMir2Lir::CompilerInitializeRegAlloc() { reg_pool_->next_core_reg_ = 2; reg_pool_->next_sp_reg_ = 0; reg_pool_->next_dp_reg_ = 0; + + CompilerPostInitializeRegAlloc(); } /* @@ -814,17 +837,17 @@ LIR* ArmMir2Lir::CheckSuspendUsingLoad() { uint64_t ArmMir2Lir::GetTargetInstFlags(int opcode) { DCHECK(!IsPseudoLirOp(opcode)); - return ArmMir2Lir::EncodingMap[opcode].flags; + return GetEncoder(opcode)->flags; } const char* ArmMir2Lir::GetTargetInstName(int opcode) { DCHECK(!IsPseudoLirOp(opcode)); - return ArmMir2Lir::EncodingMap[opcode].name; + return GetEncoder(opcode)->name; } const char* ArmMir2Lir::GetTargetInstFmt(int opcode) { DCHECK(!IsPseudoLirOp(opcode)); - return ArmMir2Lir::EncodingMap[opcode].fmt; + return GetEncoder(opcode)->fmt; } /* @@ -1009,8 +1032,15 @@ void ArmMir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) { GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2], true); break; default: - LOG(FATAL) << "Unexpected opcode: " << mir->dalvikInsn.opcode; + GenMoreMachineSpecificExtendedMethodMIR(bb, mir); + // LOG(FATAL) << "Unexpected opcode: " << mir->dalvikInsn.opcode; } } +void ArmMir2Lir::GenMoreMachineSpecificExtendedMethodMIR(BasicBlock*, MIR*){ + // nothing here +} + +void ArmMir2Lir::ApplyArchOptimizations(LIR*, LIR*, BasicBlock*) { +} } // namespace art diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc index 2ef92f851b..0a2a969374 100644 --- a/compiler/dex/quick/arm/utility_arm.cc +++ b/compiler/dex/quick/arm/utility_arm.cc @@ -282,6 +282,11 @@ LIR* ArmMir2Lir::OpReg(OpKind op, RegStorage r_dest_src) { return NewLIR1(opcode, r_dest_src.GetReg()); } +LIR* ArmMir2Lir::OpBkpt() { + LOG(ERROR) << "Inserting breakpoint"; + return NewLIR0(kThumbBkpt); +} + LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_src2, int shift) { bool thumb_form = @@ -399,15 +404,15 @@ LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_s break; } DCHECK(!IsPseudoLirOp(opcode)); - if (EncodingMap[opcode].flags & IS_BINARY_OP) { + if (GetEncoder(opcode)->flags & IS_BINARY_OP) { return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg()); - } else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) { - if (EncodingMap[opcode].field_loc[2].kind == kFmtShift) { + } else if (GetEncoder(opcode)->flags & IS_TERTIARY_OP) { + if (GetEncoder(opcode)->field_loc[2].kind == kFmtShift) { return NewLIR3(opcode, r_dest_src1.GetReg(), r_src2.GetReg(), shift); } else { return NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), r_src2.GetReg()); } - } else if (EncodingMap[opcode].flags & IS_QUAD_OP) { + } else if (GetEncoder(opcode)->flags & IS_QUAD_OP) { return NewLIR4(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), r_src2.GetReg(), shift); } else { LOG(FATAL) << "Unexpected encoding operand count"; @@ -498,10 +503,10 @@ LIR* ArmMir2Lir::OpRegRegRegShift(OpKind op, RegStorage r_dest, RegStorage r_src break; } DCHECK(!IsPseudoLirOp(opcode)); - if (EncodingMap[opcode].flags & IS_QUAD_OP) { + if (GetEncoder(opcode)->flags & IS_QUAD_OP) { return NewLIR4(opcode, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg(), shift); } else { - DCHECK(EncodingMap[opcode].flags & IS_TERTIARY_OP); + DCHECK(GetEncoder(opcode)->flags & IS_TERTIARY_OP); return NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg()); } } @@ -643,7 +648,7 @@ LIR* ArmMir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, in RegStorage r_scratch = AllocTemp(); LoadConstant(r_scratch, value); LIR* res; - if (EncodingMap[alt_opcode].flags & IS_QUAD_OP) + if (GetEncoder(alt_opcode)->flags & IS_QUAD_OP) res = NewLIR4(alt_opcode, r_dest.GetReg(), r_src1.GetReg(), r_scratch.GetReg(), 0); else res = NewLIR3(alt_opcode, r_dest.GetReg(), r_src1.GetReg(), r_scratch.GetReg()); |