From 8cf9540abd940951b8ce40506cba2c0628a55677 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 13 Jul 2012 23:24:42 -0400 Subject: [PATCH] Filter: ensure logical operator merge is always s64 Signed-off-by: Mathieu Desnoyers --- src/lib/lttng-ctl/filter-bytecode.h | 14 +++++++--- .../filter-visitor-generate-bytecode.c | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/lib/lttng-ctl/filter-bytecode.h b/src/lib/lttng-ctl/filter-bytecode.h index a846ec7a7..1bb00dd45 100644 --- a/src/lib/lttng-ctl/filter-bytecode.h +++ b/src/lib/lttng-ctl/filter-bytecode.h @@ -115,10 +115,6 @@ enum filter_op { /* logical */ FILTER_OP_AND, FILTER_OP_OR, - FILTER_OP_AND_S64, - FILTER_OP_OR_S64, - FILTER_OP_AND_DOUBLE, - FILTER_OP_OR_DOUBLE, /* load */ FILTER_OP_LOAD_FIELD_REF, @@ -131,6 +127,11 @@ enum filter_op { FILTER_OP_LOAD_S64, FILTER_OP_LOAD_DOUBLE, + /* cast */ + FILTER_OP_CAST_TO_S64, + FILTER_OP_CAST_DOUBLE_TO_S64, + FILTER_OP_CAST_NOP, + NR_FILTER_OPS, }; @@ -158,6 +159,11 @@ struct logical_op { uint16_t skip_offset; /* bytecode insn, if skip second test */ } __attribute__((packed)); +struct cast_op { + filter_opcode_t op; + uint8_t reg; /* enum filter_register */ +} __attribute__((packed)); + struct return_op { filter_opcode_t op; } __attribute__((packed)); diff --git a/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c b/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c index 8c8bf51ce..7ee35fded 100644 --- a/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c @@ -377,6 +377,9 @@ int visit_node_binary(struct filter_parser_ctx *ctx, struct ir_op *node) return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn)); } +/* + * A logical op always return a s64 (1 or 0). + */ static int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) { @@ -389,6 +392,18 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) ret = recursive_visit_gen_bytecode(ctx, node->u.binary.left); if (ret) return ret; + /* Cast to s64 if float or field ref */ + if (node->u.binary.left->data_type == IR_DATA_FIELD_REF + || node->u.binary.left->data_type == IR_DATA_FLOAT) { + struct cast_op cast_insn; + + cast_insn.op = FILTER_OP_CAST_TO_S64; + cast_insn.reg = REG_R0; + ret = bytecode_push(&ctx->bytecode, &cast_insn, + 1, sizeof(cast_insn)); + if (ret) + return ret; + } switch (node->u.logical.type) { default: fprintf(stderr, "[error] Unknown node type in %s\n", @@ -411,6 +426,18 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) ret = recursive_visit_gen_bytecode(ctx, node->u.binary.right); if (ret) return ret; + /* Cast to s64 if float or field ref */ + if (node->u.binary.right->data_type == IR_DATA_FIELD_REF + || node->u.binary.right->data_type == IR_DATA_FLOAT) { + struct cast_op cast_insn; + + cast_insn.op = FILTER_OP_CAST_TO_S64; + cast_insn.reg = REG_R0; + ret = bytecode_push(&ctx->bytecode, &cast_insn, + 1, sizeof(cast_insn)); + if (ret) + return ret; + } /* We now know where the logical op can skip. */ target_loc = (uint16_t) bytecode_get_len(&ctx->bytecode->b); ret = bytecode_patch(&ctx->bytecode, -- 2.34.1