Filter: ensure logical operator merge is always s64
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 14 Jul 2012 03:24:42 +0000 (23:24 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 14 Jul 2012 03:24:42 +0000 (23:24 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
src/lib/lttng-ctl/filter-bytecode.h
src/lib/lttng-ctl/filter-visitor-generate-bytecode.c

index a846ec7a72cc30d9213d65139dc70224d3866392..1bb00dd4577afe0f095c92b375e53eab5c40f41d 100644 (file)
@@ -115,10 +115,6 @@ enum filter_op {
        /* logical */
        FILTER_OP_AND,
        FILTER_OP_OR,
        /* 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,
 
        /* load */
        FILTER_OP_LOAD_FIELD_REF,
@@ -131,6 +127,11 @@ enum filter_op {
        FILTER_OP_LOAD_S64,
        FILTER_OP_LOAD_DOUBLE,
 
        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,
 };
 
        NR_FILTER_OPS,
 };
 
@@ -158,6 +159,11 @@ struct logical_op {
        uint16_t skip_offset;   /* bytecode insn, if skip second test */
 } __attribute__((packed));
 
        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));
 struct return_op {
        filter_opcode_t op;
 } __attribute__((packed));
index 8c8bf51ce26b07e8dc0576c3f232869c4292a8db..7ee35fded2ac91a7642aff6450d092f6504fed70 100644 (file)
@@ -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));
 }
 
        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)
 {
 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;
        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",
        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;
        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,
        /* We now know where the logical op can skip. */
        target_loc = (uint16_t) bytecode_get_len(&ctx->bytecode->b);
        ret = bytecode_patch(&ctx->bytecode,
This page took 0.035611 seconds and 4 git commands to generate.