summaryrefslogtreecommitdiff
path: root/src/compiler_llvm/gbc_expander.cc
diff options
context:
space:
mode:
author TDYa127 <tdy@google.com> 2012-07-23 03:20:39 -0700
committer Shih-wei Liao <sliao@google.com> 2012-09-15 04:15:17 -0700
commita1b2185820e6080864d18a35759cc046dc4ee578 (patch)
tree01a8350e23fcf64a505c5bc9763775334411f96d /src/compiler_llvm/gbc_expander.cc
parent9a129457c233b653c7a8f65c963509267252b0a7 (diff)
Starting to implement fly2iceland.
Thanks to logan: Fix WIP FPCompare implementation. Change-Id: Ia8816d7092bc99d87ccb8abf524dad0e5fd5b7bc
Diffstat (limited to 'src/compiler_llvm/gbc_expander.cc')
-rw-r--r--src/compiler_llvm/gbc_expander.cc86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index dd16ef7c7b..f29cab1fa2 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -175,6 +175,19 @@ class GBCExpanderPass : public llvm::FunctionPass {
void Expand_UpdateDexPC(llvm::Value* dex_pc_value);
+ //----------------------------------------------------------------------------
+ // Quick
+ //----------------------------------------------------------------------------
+
+ llvm::Value* Expand_FPCompare(llvm::Value* src1_value,
+ llvm::Value* src2_value,
+ bool gt_bias);
+
+ llvm::Value* Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value);
+
+ llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq,
+ llvm::Value* cmp_lt);
+
public:
static char ID;
@@ -977,6 +990,41 @@ bool GBCExpanderPass::InsertStackOverflowCheck(llvm::Function& func) {
return EmitStackOverflowCheck(&*first_non_alloca);
}
+llvm::Value* GBCExpanderPass::Expand_FPCompare(llvm::Value* src1_value,
+ llvm::Value* src2_value,
+ bool gt_bias) {
+ llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value);
+ llvm::Value* cmp_lt;
+
+ if (gt_bias) {
+ cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value);
+ } else {
+ cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value);
+ }
+
+ return EmitCompareResultSelection(cmp_eq, cmp_lt);
+}
+
+llvm::Value* GBCExpanderPass::Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value) {
+ llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value);
+ llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value);
+
+ return EmitCompareResultSelection(cmp_eq, cmp_lt);
+}
+
+llvm::Value* GBCExpanderPass::EmitCompareResultSelection(llvm::Value* cmp_eq,
+ llvm::Value* cmp_lt) {
+
+ llvm::Constant* zero = irb_.getJInt(0);
+ llvm::Constant* pos1 = irb_.getJInt(1);
+ llvm::Constant* neg1 = irb_.getJInt(-1);
+
+ llvm::Value* result_lt = irb_.CreateSelect(cmp_lt, neg1, pos1);
+ llvm::Value* result_eq = irb_.CreateSelect(cmp_eq, zero, result_lt);
+
+ return result_eq;
+}
+
llvm::Value*
GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
llvm::CallInst& call_inst) {
@@ -1515,6 +1563,44 @@ GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
Expand_UpdateDexPC(call_inst.getArgOperand(0));
return NULL;
}
+
+
+ //==- Quick ------------------------------------------------------------==//
+ case IntrinsicHelper::IntToChar: {
+ return irb_.CreateZExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJCharTy()),
+ irb_.getJIntTy());
+ }
+ case IntrinsicHelper::IntToShort: {
+ return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJShortTy()),
+ irb_.getJIntTy());
+ }
+ case IntrinsicHelper::IntToByte: {
+ return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJByteTy()),
+ irb_.getJIntTy());
+ }
+ case IntrinsicHelper::CmplFloat:
+ case IntrinsicHelper::CmplDouble: {
+ return Expand_FPCompare(call_inst.getArgOperand(0), call_inst.getArgOperand(0), false);
+ }
+ case IntrinsicHelper::CmpgFloat:
+ case IntrinsicHelper::CmpgDouble: {
+ return Expand_FPCompare(call_inst.getArgOperand(0), call_inst.getArgOperand(0), true);
+ }
+ case IntrinsicHelper::CmpLong: {
+ return Expand_LongCompare(call_inst.getArgOperand(0), call_inst.getArgOperand(0));
+ }
+ case greenland::IntrinsicHelper::SHLLong: {
+ }
+ case greenland::IntrinsicHelper::SHRLong: {
+ }
+ case greenland::IntrinsicHelper::USHRLong: {
+ }
+ case greenland::IntrinsicHelper::SHLInt: {
+ }
+ case greenland::IntrinsicHelper::SHRInt: {
+ }
+ case greenland::IntrinsicHelper::USHRInt: {
+ }
default: {
const IntrinsicHelper::IntrinsicInfo& intr_info =
IntrinsicHelper::GetInfo(intr_id);