aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2011-11-22 21:41:12 +0200
committerPekka Enberg <penberg@kernel.org>2011-11-22 22:06:37 +0200
commitce2aacc7ce377c9871e8a5c362d2c7c0aae8ebd6 (patch)
tree8618eebd86d2fa12fd55730fb95d198732017017
parent58f7c712b643db22fe46ecfb9fa39a93a57ddfa9 (diff)
downloadsparse-ce2aacc7ce377c9871e8a5c362d2c7c0aae8ebd6.tar.gz
sparse, llvm: FP comparison op code generation
This patch implements code generation for floating point versions of OP_BINCMP. Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Christopher Li <sparse@chrisli.org> Cc: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--sparse-llvm.c29
-rw-r--r--validation/backend/cmp-ops.c30
2 files changed, 57 insertions, 2 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 4ef02a1f..0674ef3e 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -391,6 +391,25 @@ static LLVMTypeRef pseudo_type(struct function *fn, struct instruction *insn, ps
return result;
}
+static LLVMRealPredicate translate_fop(int opcode)
+{
+ static const LLVMRealPredicate trans_tbl[] = {
+ [OP_SET_EQ] = LLVMRealOEQ,
+ [OP_SET_NE] = LLVMRealUNE,
+ [OP_SET_LE] = LLVMRealOLE,
+ [OP_SET_GE] = LLVMRealOGE,
+ [OP_SET_LT] = LLVMRealOLT,
+ [OP_SET_GT] = LLVMRealOGT,
+ /* Are these used with FP? */
+ [OP_SET_B] = LLVMRealOLT,
+ [OP_SET_A] = LLVMRealOGT,
+ [OP_SET_BE] = LLVMRealOLE,
+ [OP_SET_AE] = LLVMRealOGE,
+ };
+
+ return trans_tbl[opcode];
+}
+
static LLVMIntPredicate translate_op(int opcode)
{
static const LLVMIntPredicate trans_tbl[] = {
@@ -512,9 +531,15 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
/* Binary comparison */
case OP_BINCMP ... OP_BINCMP_END: {
- LLVMIntPredicate op = translate_op(insn->opcode);
+ if (LLVMGetTypeKind(LLVMTypeOf(lhs)) == LLVMIntegerTypeKind) {
+ LLVMIntPredicate op = translate_op(insn->opcode);
- target = LLVMBuildICmp(fn->builder, op, lhs, rhs, target_name);
+ target = LLVMBuildICmp(fn->builder, op, lhs, rhs, target_name);
+ } else {
+ LLVMRealPredicate op = translate_fop(insn->opcode);
+
+ target = LLVMBuildFCmp(fn->builder, op, lhs, rhs, target_name);
+ }
break;
}
default:
diff --git a/validation/backend/cmp-ops.c b/validation/backend/cmp-ops.c
index 7bbc81ce..a5f736d7 100644
--- a/validation/backend/cmp-ops.c
+++ b/validation/backend/cmp-ops.c
@@ -48,6 +48,36 @@ static int setae(unsigned int x, unsigned int y)
return x >= y;
}
+static int setfe(float x, float y)
+{
+ return x == y;
+}
+
+static int setfne(float x, float y)
+{
+ return x != y;
+}
+
+static int setfl(float x, float y)
+{
+ return x < y;
+}
+
+static int setfg(float x, float y)
+{
+ return x > y;
+}
+
+static int setfle(float x, float y)
+{
+ return x <= y;
+}
+
+static int setfge(float x, float y)
+{
+ return x >= y;
+}
+
/*
* check-name: Comparison operator code generation
* check-command: ./sparsec -c $file -o tmp.o