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) {
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index a34d206..edde6ff 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -289,6 +289,11 @@
                                               IntArithmKind arithm,
                                               JType op_jty);
 
+  llvm::Value* EmitFPArithmResultComputation(uint32_t dex_pc,
+                                             llvm::Value* lhs,
+                                             llvm::Value* rhs,
+                                             FPArithmKind arithm);
+
   void EmitGuard_DivZeroException(uint32_t dex_pc,
                                   llvm::Value* denominator,
                                   JType op_jty);