aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sparse-llvm.c
diff options
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 /sparse-llvm.c
parent58f7c712b643db22fe46ecfb9fa39a93a57ddfa9 (diff)
downloadsparse-dev-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>
Diffstat (limited to 'sparse-llvm.c')
-rw-r--r--sparse-llvm.c29
1 files changed, 27 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: