X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Ffilter-visitor-generate-bytecode.c;h=7ee35fded2ac91a7642aff6450d092f6504fed70;hp=e940e2c81ab6f85ea8313018d58f5fc7d51f8e6e;hb=8cf9540abd940951b8ce40506cba2c0628a55677;hpb=953192ba6eb2118c22bcfcb4bcd813f141b407e7 diff --git a/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c b/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c index e940e2c81..7ee35fded 100644 --- a/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c @@ -39,9 +39,9 @@ int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, struct ir_op *node); static -int bytecode_init(struct filter_bytecode_alloc **fb) +int bytecode_init(struct lttng_filter_bytecode_alloc **fb) { - *fb = calloc(sizeof(struct filter_bytecode_alloc) + INIT_ALLOC_SIZE, 1); + *fb = calloc(sizeof(struct lttng_filter_bytecode_alloc) + INIT_ALLOC_SIZE, 1); if (!*fb) { return -ENOMEM; } else { @@ -51,7 +51,7 @@ int bytecode_init(struct filter_bytecode_alloc **fb) } static -int32_t bytecode_reserve(struct filter_bytecode_alloc **fb, uint32_t align, uint32_t len) +int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align, uint32_t len) { int32_t ret; uint32_t padding = offset_align((*fb)->b.len, align); @@ -64,7 +64,7 @@ int32_t bytecode_reserve(struct filter_bytecode_alloc **fb, uint32_t align, uint if (new_len > 0xFFFF) return -EINVAL; - *fb = realloc(*fb, sizeof(struct filter_bytecode_alloc) + new_len); + *fb = realloc(*fb, sizeof(struct lttng_filter_bytecode_alloc) + new_len); if (!*fb) return -ENOMEM; memset(&(*fb)->b.data[old_len], 0, new_len - old_len); @@ -77,7 +77,7 @@ int32_t bytecode_reserve(struct filter_bytecode_alloc **fb, uint32_t align, uint } static -int bytecode_push(struct filter_bytecode_alloc **fb, const void *data, +int bytecode_push(struct lttng_filter_bytecode_alloc **fb, const void *data, uint32_t align, uint32_t len) { int32_t offset; @@ -90,7 +90,7 @@ int bytecode_push(struct filter_bytecode_alloc **fb, const void *data, } static -int bytecode_push_logical(struct filter_bytecode_alloc **fb, +int bytecode_push_logical(struct lttng_filter_bytecode_alloc **fb, struct logical_op *data, uint32_t align, uint32_t len, uint16_t *skip_offset) @@ -108,7 +108,7 @@ int bytecode_push_logical(struct filter_bytecode_alloc **fb, } static -int bytecode_patch(struct filter_bytecode_alloc **fb, +int bytecode_patch(struct lttng_filter_bytecode_alloc **fb, const void *data, uint16_t offset, uint32_t len) @@ -200,6 +200,24 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) free(insn); return ret; } + case IR_DATA_FLOAT: + { + struct load_op *insn; + uint32_t insn_len = sizeof(struct load_op) + + sizeof(struct literal_double); + + insn = calloc(insn_len, 1); + if (!insn) + return -ENOMEM; + insn->op = FILTER_OP_LOAD_DOUBLE; + insn->reg = reg_sel(node); + if (insn->reg == REG_ERROR) + return -EINVAL; + *(double *) insn->data = node->u.load.u.flt; + ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); + free(insn); + return ret; + } case IR_DATA_FIELD_REF: { struct load_op *insn; @@ -217,9 +235,8 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) memcpy(insn->data, &ref_offset, sizeof(ref_offset)); if (insn->reg == REG_ERROR) return -EINVAL; - /* reloc_offset points to struct field_ref */ + /* reloc_offset points to struct load_op */ reloc_offset = bytecode_get_len(&ctx->bytecode->b); - reloc_offset += sizeof(struct load_op); ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); if (ret) { free(insn); @@ -360,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) { @@ -372,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", @@ -394,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,