Implement floating-point binary arithmetic instructions.
Change-Id: Ie996a036c560713704a0c820a75dd6548bdb0047
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 734a381..e001f4a 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -1966,11 +1966,59 @@
FPArithmKind arithm,
JType op_jty,
bool is_2addr) {
- // UNIMPLEMENTED(WARNING);
+
+ Instruction::DecodedInstruction dec_insn(insn);
+
+ DCHECK(op_jty == kFloat || op_jty == kDouble) << op_jty;
+
+ llvm::Value* src1_value;
+ llvm::Value* src2_value;
+
+ if (is_2addr) {
+ src1_value = EmitLoadDalvikReg(dec_insn.vA_, op_jty, kAccurate);
+ src2_value = EmitLoadDalvikReg(dec_insn.vB_, op_jty, kAccurate);
+ } else {
+ src1_value = EmitLoadDalvikReg(dec_insn.vB_, op_jty, kAccurate);
+ src2_value = EmitLoadDalvikReg(dec_insn.vC_, op_jty, kAccurate);
+ }
+
+ llvm::Value* result_value =
+ EmitFPArithmResultComputation(dex_pc, src1_value, src2_value, arithm);
+
+ EmitStoreDalvikReg(dec_insn.vA_, op_jty, kAccurate, result_value);
+
irb_.CreateBr(GetNextBasicBlock(dex_pc));
}
+llvm::Value*
+MethodCompiler::EmitFPArithmResultComputation(uint32_t dex_pc,
+ llvm::Value *lhs,
+ llvm::Value *rhs,
+ FPArithmKind arithm) {
+ switch (arithm) {
+ case kFPArithm_Add:
+ return irb_.CreateFAdd(lhs, rhs);
+
+ case kFPArithm_Sub:
+ return irb_.CreateFSub(lhs, rhs);
+
+ case kFPArithm_Mul:
+ return irb_.CreateFMul(lhs, rhs);
+
+ case kFPArithm_Div:
+ return irb_.CreateFDiv(lhs, rhs);
+
+ case kFPArithm_Rem:
+ return irb_.CreateFRem(lhs, rhs);
+
+ default:
+ LOG(FATAL) << "Unknown floating-point arithmetic kind: " << arithm;
+ return NULL;
+ }
+}
+
+
void MethodCompiler::EmitGuard_DivZeroException(uint32_t dex_pc,
llvm::Value* denominator,
JType op_jty) {