AArch64: Enable FLOAT and DOUBLE opcodes
This patch enables all the DOUBLE and FLOAT opcodes except for REM ones.
It has been tested and passes all Dalvik tests except for:
failed: 018-stack-overflow[pid=1076]
failed: 107-int-math2[pid=1593]
Change-Id: I581f219bde354e3402aa3ad6e24ef15566da5f78
Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
diff --git a/compiler/dex/quick/arm64/fp_arm64.cc b/compiler/dex/quick/arm64/fp_arm64.cc
index 87ab6fe..882ee66 100644
--- a/compiler/dex/quick/arm64/fp_arm64.cc
+++ b/compiler/dex/quick/arm64/fp_arm64.cc
@@ -25,10 +25,6 @@
int op = kA64Brk1d;
RegLocation rl_result;
- /*
- * Don't attempt to optimize register usage since these opcodes call out to
- * the handlers.
- */
switch (opcode) {
case Instruction::ADD_FLOAT_2ADDR:
case Instruction::ADD_FLOAT:
@@ -119,49 +115,75 @@
RegLocation rl_dest, RegLocation rl_src) {
int op = kA64Brk1d;
RegLocation rl_result;
+ RegisterClass src_reg_class = kInvalidRegClass;
+ RegisterClass dst_reg_class = kInvalidRegClass;
switch (opcode) {
case Instruction::INT_TO_FLOAT:
op = kA64Scvtf2fw;
+ src_reg_class = kCoreReg;
+ dst_reg_class = kFPReg;
break;
case Instruction::FLOAT_TO_INT:
op = kA64Fcvtzs2wf;
+ src_reg_class = kFPReg;
+ dst_reg_class = kCoreReg;
break;
case Instruction::DOUBLE_TO_FLOAT:
op = kA64Fcvt2sS;
+ src_reg_class = kFPReg;
+ dst_reg_class = kFPReg;
break;
case Instruction::FLOAT_TO_DOUBLE:
op = kA64Fcvt2Ss;
+ src_reg_class = kFPReg;
+ dst_reg_class = kFPReg;
break;
case Instruction::INT_TO_DOUBLE:
op = FWIDE(kA64Scvtf2fw);
+ src_reg_class = kCoreReg;
+ dst_reg_class = kFPReg;
break;
case Instruction::DOUBLE_TO_INT:
op = FWIDE(kA64Fcvtzs2wf);
+ src_reg_class = kFPReg;
+ dst_reg_class = kCoreReg;
break;
case Instruction::LONG_TO_DOUBLE:
op = FWIDE(kA64Scvtf2fx);
+ src_reg_class = kCoreReg;
+ dst_reg_class = kFPReg;
break;
case Instruction::FLOAT_TO_LONG:
op = kA64Fcvtzs2xf;
+ src_reg_class = kFPReg;
+ dst_reg_class = kCoreReg;
break;
case Instruction::LONG_TO_FLOAT:
op = kA64Scvtf2fx;
+ src_reg_class = kCoreReg;
+ dst_reg_class = kFPReg;
break;
case Instruction::DOUBLE_TO_LONG:
op = FWIDE(kA64Fcvtzs2xf);
+ src_reg_class = kFPReg;
+ dst_reg_class = kCoreReg;
break;
default:
LOG(FATAL) << "Unexpected opcode: " << opcode;
}
+ DCHECK_NE(src_reg_class, kInvalidRegClass);
+ DCHECK_NE(dst_reg_class, kInvalidRegClass);
+ DCHECK_NE(op, kA64Brk1d);
+
if (rl_src.wide) {
- rl_src = LoadValueWide(rl_src, kFPReg);
+ rl_src = LoadValueWide(rl_src, src_reg_class);
} else {
- rl_src = LoadValue(rl_src, kFPReg);
+ rl_src = LoadValue(rl_src, src_reg_class);
}
- rl_result = EvalLoc(rl_dest, kFPReg, true);
+ rl_result = EvalLoc(rl_dest, dst_reg_class, true);
NewLIR2(op, rl_result.reg.GetReg(), rl_src.reg.GetReg());
if (rl_dest.wide) {
@@ -296,25 +318,11 @@
}
bool Arm64Mir2Lir::GenInlinedSqrt(CallInfo* info) {
- // TODO(Arm64): implement this.
- UNIMPLEMENTED(FATAL) << "GenInlinedSqrt not implemented for Arm64";
-
- DCHECK_EQ(cu_->instruction_set, kArm64);
- LIR *branch;
RegLocation rl_src = info->args[0];
RegLocation rl_dest = InlineTargetWide(info); // double place for result
rl_src = LoadValueWide(rl_src, kFPReg);
RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true);
NewLIR2(FWIDE(kA64Fsqrt2ff), rl_result.reg.GetReg(), rl_src.reg.GetReg());
- NewLIR2(FWIDE(kA64Fcmp2ff), rl_result.reg.GetReg(), rl_result.reg.GetReg());
- branch = NewLIR2(kA64B2ct, kArmCondEq, 0);
- ClobberCallerSave();
- LockCallTemps(); // Using fixed registers
- RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(8, pSqrt));
- // NewLIR3(kThumb2Fmrrd, r0, r1, rl_src.reg.GetReg());
- NewLIR1(kA64Blr1x, r_tgt.GetReg());
- // NewLIR3(kThumb2Fmdrr, rl_result.reg.GetReg(), r0, r1);
- branch->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
return true;
}