diff options
author | Zheng Xu <zheng.xu@arm.com> | 2014-06-03 16:22:23 +0800 |
---|---|---|
committer | Zheng Xu <zheng.xu@arm.com> | 2014-06-04 16:15:10 +0800 |
commit | 511c8a653d5896e81428393a1c3d427da64e36f3 (patch) | |
tree | 2d286df3b09a689a313bccd8925eb29fc2d1c4eb | |
parent | 57795db7d44bcd6d106481fa192691400b2358c8 (diff) | |
download | art-511c8a653d5896e81428393a1c3d427da64e36f3.zip art-511c8a653d5896e81428393a1c3d427da64e36f3.tar.gz art-511c8a653d5896e81428393a1c3d427da64e36f3.tar.bz2 |
AArch64: Fix cmp-long and method with long arguments.
1. Fix cmp-long.
2. Use single register to pass long argument.
3. Flush StackReference<ArtMethod> on arm64 the same as in common code.
3. Fix the mismatch in calculate reg offset.
Change-Id: Ie2723260fb143512e4da6ee88d4f3aded80d3d5e
-rw-r--r-- | compiler/dex/quick/arm64/int_arm64.cc | 12 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/target_arm64.cc | 16 | ||||
-rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 2 | ||||
-rw-r--r-- | runtime/stack.h | 64 |
4 files changed, 44 insertions, 50 deletions
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc index 7ebb496..0a76b9b 100644 --- a/compiler/dex/quick/arm64/int_arm64.cc +++ b/compiler/dex/quick/arm64/int_arm64.cc @@ -41,8 +41,8 @@ void Arm64Mir2Lir::OpEndIT(LIR* it) { /* * 64-bit 3way compare function. * cmp xA, xB - * csinc wC, wzr, wzr, eq - * csneg wC, wC, wC, le + * csinc wC, wzr, wzr, eq // wC = (xA == xB) ? 0 : 1 + * csneg wC, wC, wC, ge // wC = (xA >= xB) ? wC : -wC */ void Arm64Mir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { @@ -52,10 +52,10 @@ void Arm64Mir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, rl_result = EvalLoc(rl_dest, kCoreReg, true); OpRegReg(kOpCmp, rl_src1.reg, rl_src2.reg); - NewLIR4(WIDE(kA64Csinc4rrrc), rl_result.reg.GetReg(), rxzr, rxzr, kArmCondEq); - NewLIR4(WIDE(kA64Csneg4rrrc), rl_result.reg.GetReg(), rl_result.reg.GetReg(), - rl_result.reg.GetReg(), kArmCondLe); - StoreValueWide(rl_dest, rl_result); + NewLIR4(kA64Csinc4rrrc, rl_result.reg.GetReg(), rwzr, rwzr, kArmCondEq); + NewLIR4(kA64Csneg4rrrc, rl_result.reg.GetReg(), rl_result.reg.GetReg(), + rl_result.reg.GetReg(), kArmCondGe); + StoreValue(rl_dest, rl_result); } void Arm64Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest, diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index 7539392..0524191 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -839,7 +839,7 @@ void Arm64Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { int num_fpr_used = 0; /* - * Dummy up a RegLocation for the incoming Method* + * Dummy up a RegLocation for the incoming StackReference<mirror::ArtMethod> * It will attempt to keep kArg0 live (or copy it to home location * if promoted). */ @@ -848,14 +848,10 @@ void Arm64Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { rl_src.reg = TargetReg(kArg0); rl_src.home = false; MarkLive(rl_src); - - // rl_method might be 32-bit, but ArtMethod* on stack is 64-bit, so always flush it. - StoreWordDisp(TargetReg(kSp), 0, TargetReg(kArg0)); - - // If Method* has been promoted, load it, - // otherwise, rl_method is the 32-bit value on [sp], and has already been loaded. + StoreValue(rl_method, rl_src); + // If Method* has been promoted, explicitly flush if (rl_method.location == kLocPhysReg) { - StoreValue(rl_method, rl_src); + StoreRefDisp(TargetReg(kSp), 0, TargetReg(kArg0)); } if (cu_->num_ins == 0) { @@ -912,9 +908,7 @@ int Arm64Mir2Lir::LoadArgRegs(CallInfo* info, int call_state, RegLocation rl_arg = info->args[next_arg++]; rl_arg = UpdateRawLoc(rl_arg); if (rl_arg.wide && (next_reg <= TargetReg(kArg2).GetReg())) { - RegStorage r_tmp(RegStorage::k64BitPair, next_reg, next_reg + 1); - LoadValueDirectWideFixed(rl_arg, r_tmp); - next_reg++; + LoadValueDirectWideFixed(rl_arg, RegStorage::Solo64(next_reg)); next_arg++; } else { if (rl_arg.wide) { diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 1817fd3..842533b 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -434,7 +434,7 @@ INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegLocationRegLocationRegLocation, Re */ void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { /* - * Dummy up a RegLocation for the incoming Method* + * Dummy up a RegLocation for the incoming StackReference<mirror::ArtMethod> * It will attempt to keep kArg0 live (or copy it to home location * if promoted). */ diff --git a/runtime/stack.h b/runtime/stack.h index fabdd4f..e1c8c80 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -599,37 +599,37 @@ class StackVisitor { * on location in frame as long as code generator itself knows how * to access them. * - * +------------------------+ - * | IN[ins-1] | {Note: resides in caller's frame} - * | . | - * | IN[0] | - * | caller's Method* | - * +========================+ {Note: start of callee's frame} - * | core callee-save spill | {variable sized} - * +------------------------+ - * | fp callee-save spill | - * +------------------------+ - * | filler word | {For compatibility, if V[locals-1] used as wide - * +------------------------+ - * | V[locals-1] | - * | V[locals-2] | - * | . | - * | . | ... (reg == 2) - * | V[1] | ... (reg == 1) - * | V[0] | ... (reg == 0) <---- "locals_start" - * +------------------------+ - * | Compiler temp region | ... (reg <= -3) - * | | - * | | - * +------------------------+ - * | stack alignment padding| {0 to (kStackAlignWords-1) of padding} - * +------------------------+ - * | OUT[outs-1] | - * | OUT[outs-2] | - * | . | - * | OUT[0] | - * | curMethod* | ... (reg == -2) <<== sp, 16-byte aligned - * +========================+ + * +---------------------------+ + * | IN[ins-1] | {Note: resides in caller's frame} + * | . | + * | IN[0] | + * | caller's ArtMethod | ... StackReference<ArtMethod> + * +===========================+ {Note: start of callee's frame} + * | core callee-save spill | {variable sized} + * +---------------------------+ + * | fp callee-save spill | + * +---------------------------+ + * | filler word | {For compatibility, if V[locals-1] used as wide + * +---------------------------+ + * | V[locals-1] | + * | V[locals-2] | + * | . | + * | . | ... (reg == 2) + * | V[1] | ... (reg == 1) + * | V[0] | ... (reg == 0) <---- "locals_start" + * +---------------------------+ + * | Compiler temp region | ... (reg <= -3) + * | | + * | | + * +---------------------------+ + * | stack alignment padding | {0 to (kStackAlignWords-1) of padding} + * +---------------------------+ + * | OUT[outs-1] | + * | OUT[outs-2] | + * | . | + * | OUT[0] | + * | StackReference<ArtMethod> | ... (reg == -2) <<== sp, 16-byte aligned + * +===========================+ */ static int GetVRegOffset(const DexFile::CodeItem* code_item, uint32_t core_spills, uint32_t fp_spills, @@ -661,7 +661,7 @@ class StackVisitor { return locals_start + (reg * sizeof(uint32_t)); } else { // Handle ins. - return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + GetBytesPerGprSpillLocation(isa); + return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(StackReference<mirror::ArtMethod>); } } |