summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZheng Xu <zheng.xu@arm.com>2014-06-03 16:22:23 +0800
committerZheng Xu <zheng.xu@arm.com>2014-06-04 16:15:10 +0800
commit511c8a653d5896e81428393a1c3d427da64e36f3 (patch)
tree2d286df3b09a689a313bccd8925eb29fc2d1c4eb
parent57795db7d44bcd6d106481fa192691400b2358c8 (diff)
downloadart-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.cc12
-rw-r--r--compiler/dex/quick/arm64/target_arm64.cc16
-rw-r--r--compiler/dex/quick/gen_invoke.cc2
-rw-r--r--runtime/stack.h64
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>);
}
}