diff options
author | Pekka Enberg <penberg@kernel.org> | 2011-11-22 21:41:12 +0200 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2011-11-22 22:06:37 +0200 |
commit | ce2aacc7ce377c9871e8a5c362d2c7c0aae8ebd6 (patch) | |
tree | 8618eebd86d2fa12fd55730fb95d198732017017 | |
parent | 58f7c712b643db22fe46ecfb9fa39a93a57ddfa9 (diff) | |
download | sparse-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.c | 29 | ||||
-rw-r--r-- | validation/backend/cmp-ops.c | 30 |
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 |