2 * lttng-filter-interpreter.c
4 * LTTng UST filter interpreter.
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "lttng-filter.h"
27 * -2: unknown escape char.
32 int parse_char(const char **p
)
52 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
54 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
61 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
62 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
68 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
69 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
75 if (reg
[REG_R0
].literal
) {
79 } else if (ret
== -2) {
82 /* else compare both char */
84 if (reg
[REG_R1
].literal
) {
88 } else if (ret
== -2) {
108 int lttng_filter_false(void *filter_data
,
109 const char *filter_stack_data
)
114 #ifdef INTERPRETER_USE_SWITCH
117 * Fallback for compilers that do not support taking address of labels.
121 start_pc = &bytecode->data[0]; \
122 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
124 dbg_printf("Executing op %s (%u)\n", \
125 print_op((unsigned int) *(filter_opcode_t *) pc), \
126 (unsigned int) *(filter_opcode_t *) pc); \
127 switch (*(filter_opcode_t *) pc) {
129 #define OP(name) case name
139 * Dispatch-table based interpreter.
143 start_pc = &bytecode->data[0]; \
144 pc = next_pc = start_pc; \
145 if (unlikely(pc - start_pc >= bytecode->len)) \
147 goto *dispatch[*(filter_opcode_t *) pc];
154 goto *dispatch[*(filter_opcode_t *) pc];
160 int lttng_filter_interpret_bytecode(void *filter_data
,
161 const char *filter_stack_data
)
163 struct bytecode_runtime
*bytecode
= filter_data
;
164 void *pc
, *next_pc
, *start_pc
;
167 struct reg reg
[NR_REG
];
168 #ifndef INTERPRETER_USE_SWITCH
169 static void *dispatch
[NR_FILTER_OPS
] = {
170 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
172 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
175 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
176 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
177 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
178 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
179 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
180 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
181 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
182 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
183 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
184 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
186 /* binary comparators */
187 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
188 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
189 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
190 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
191 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
192 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
194 /* string binary comparator */
195 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
196 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
197 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
198 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
199 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
200 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
202 /* s64 binary comparator */
203 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
204 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
205 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
206 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
207 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
208 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
210 /* double binary comparator */
211 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
212 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
213 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
214 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
215 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
216 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
219 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
220 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
221 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
222 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
223 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
224 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
225 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
226 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
227 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
230 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
231 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
234 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
235 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
236 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
237 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
238 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
240 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
241 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
242 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
245 [ FILTER_OP_CAST_TO_S64
] = &&LABEL_FILTER_OP_CAST_TO_S64
,
246 [ FILTER_OP_CAST_DOUBLE_TO_S64
] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64
,
247 [ FILTER_OP_CAST_NOP
] = &&LABEL_FILTER_OP_CAST_NOP
,
249 #endif /* #ifndef INTERPRETER_USE_SWITCH */
253 OP(FILTER_OP_UNKNOWN
):
254 OP(FILTER_OP_LOAD_FIELD_REF
):
255 #ifdef INTERPRETER_USE_SWITCH
257 #endif /* INTERPRETER_USE_SWITCH */
258 ERR("unknown bytecode op %u\n",
259 (unsigned int) *(filter_opcode_t
*) pc
);
263 OP(FILTER_OP_RETURN
):
274 OP(FILTER_OP_RSHIFT
):
275 OP(FILTER_OP_LSHIFT
):
276 OP(FILTER_OP_BIN_AND
):
277 OP(FILTER_OP_BIN_OR
):
278 OP(FILTER_OP_BIN_XOR
):
279 ERR("unsupported bytecode op %u\n",
280 (unsigned int) *(filter_opcode_t
*) pc
);
290 ERR("unsupported non-specialized bytecode op %u\n",
291 (unsigned int) *(filter_opcode_t
*) pc
);
295 OP(FILTER_OP_EQ_STRING
):
297 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
298 reg
[REG_R0
].type
= REG_S64
;
299 next_pc
+= sizeof(struct binary_op
);
302 OP(FILTER_OP_NE_STRING
):
304 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
305 reg
[REG_R0
].type
= REG_S64
;
306 next_pc
+= sizeof(struct binary_op
);
309 OP(FILTER_OP_GT_STRING
):
311 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
312 reg
[REG_R0
].type
= REG_S64
;
313 next_pc
+= sizeof(struct binary_op
);
316 OP(FILTER_OP_LT_STRING
):
318 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
319 reg
[REG_R0
].type
= REG_S64
;
320 next_pc
+= sizeof(struct binary_op
);
323 OP(FILTER_OP_GE_STRING
):
325 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
326 reg
[REG_R0
].type
= REG_S64
;
327 next_pc
+= sizeof(struct binary_op
);
330 OP(FILTER_OP_LE_STRING
):
332 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
333 reg
[REG_R0
].type
= REG_S64
;
334 next_pc
+= sizeof(struct binary_op
);
338 OP(FILTER_OP_EQ_S64
):
340 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
341 reg
[REG_R0
].type
= REG_S64
;
342 next_pc
+= sizeof(struct binary_op
);
345 OP(FILTER_OP_NE_S64
):
347 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
348 reg
[REG_R0
].type
= REG_S64
;
349 next_pc
+= sizeof(struct binary_op
);
352 OP(FILTER_OP_GT_S64
):
354 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
355 reg
[REG_R0
].type
= REG_S64
;
356 next_pc
+= sizeof(struct binary_op
);
359 OP(FILTER_OP_LT_S64
):
361 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
362 reg
[REG_R0
].type
= REG_S64
;
363 next_pc
+= sizeof(struct binary_op
);
366 OP(FILTER_OP_GE_S64
):
368 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
369 reg
[REG_R0
].type
= REG_S64
;
370 next_pc
+= sizeof(struct binary_op
);
373 OP(FILTER_OP_LE_S64
):
375 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
376 reg
[REG_R0
].type
= REG_S64
;
377 next_pc
+= sizeof(struct binary_op
);
381 OP(FILTER_OP_EQ_DOUBLE
):
383 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
384 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
385 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
386 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
387 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
388 reg
[REG_R0
].type
= REG_S64
;
389 next_pc
+= sizeof(struct binary_op
);
392 OP(FILTER_OP_NE_DOUBLE
):
394 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
395 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
396 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
397 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
398 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
399 reg
[REG_R0
].type
= REG_S64
;
400 next_pc
+= sizeof(struct binary_op
);
403 OP(FILTER_OP_GT_DOUBLE
):
405 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
406 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
407 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
408 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
409 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
410 reg
[REG_R0
].type
= REG_S64
;
411 next_pc
+= sizeof(struct binary_op
);
414 OP(FILTER_OP_LT_DOUBLE
):
416 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
417 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
418 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
419 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
420 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
421 reg
[REG_R0
].type
= REG_S64
;
422 next_pc
+= sizeof(struct binary_op
);
425 OP(FILTER_OP_GE_DOUBLE
):
427 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
428 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
429 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
430 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
431 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
432 reg
[REG_R0
].type
= REG_S64
;
433 next_pc
+= sizeof(struct binary_op
);
436 OP(FILTER_OP_LE_DOUBLE
):
438 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
439 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
440 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
441 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
442 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
443 reg
[REG_R0
].type
= REG_S64
;
444 next_pc
+= sizeof(struct binary_op
);
449 OP(FILTER_OP_UNARY_PLUS
):
450 OP(FILTER_OP_UNARY_MINUS
):
451 OP(FILTER_OP_UNARY_NOT
):
452 ERR("unsupported non-specialized bytecode op %u\n",
453 (unsigned int) *(filter_opcode_t
*) pc
);
458 OP(FILTER_OP_UNARY_PLUS_S64
):
459 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
461 next_pc
+= sizeof(struct unary_op
);
464 OP(FILTER_OP_UNARY_MINUS_S64
):
466 struct unary_op
*insn
= (struct unary_op
*) pc
;
468 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
469 next_pc
+= sizeof(struct unary_op
);
472 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
474 struct unary_op
*insn
= (struct unary_op
*) pc
;
476 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
477 next_pc
+= sizeof(struct unary_op
);
480 OP(FILTER_OP_UNARY_NOT_S64
):
482 struct unary_op
*insn
= (struct unary_op
*) pc
;
484 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
485 next_pc
+= sizeof(struct unary_op
);
488 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
490 struct unary_op
*insn
= (struct unary_op
*) pc
;
492 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
493 next_pc
+= sizeof(struct unary_op
);
500 struct logical_op
*insn
= (struct logical_op
*) pc
;
502 /* If REG_R0 is 0, skip and evaluate to 0 */
503 if (unlikely(reg
[REG_R0
].v
== 0)) {
504 dbg_printf("Jumping to bytecode offset %u\n",
505 (unsigned int) insn
->skip_offset
);
506 next_pc
= start_pc
+ insn
->skip_offset
;
508 next_pc
+= sizeof(struct logical_op
);
514 struct logical_op
*insn
= (struct logical_op
*) pc
;
516 /* If REG_R0 is nonzero, skip and evaluate to 1 */
518 if (unlikely(reg
[REG_R0
].v
!= 0)) {
520 dbg_printf("Jumping to bytecode offset %u\n",
521 (unsigned int) insn
->skip_offset
);
522 next_pc
= start_pc
+ insn
->skip_offset
;
524 next_pc
+= sizeof(struct logical_op
);
531 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
533 struct load_op
*insn
= (struct load_op
*) pc
;
534 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
536 dbg_printf("load field ref offset %u type string\n",
539 *(const char * const *) &filter_stack_data
[ref
->offset
];
540 if (unlikely(!reg
[insn
->reg
].str
)) {
541 dbg_printf("Filter warning: loading a NULL string.\n");
545 reg
[insn
->reg
].type
= REG_STRING
;
546 reg
[insn
->reg
].seq_len
= UINT_MAX
;
547 reg
[insn
->reg
].literal
= 0;
548 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
549 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
553 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
555 struct load_op
*insn
= (struct load_op
*) pc
;
556 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
558 dbg_printf("load field ref offset %u type sequence\n",
560 reg
[insn
->reg
].seq_len
=
561 *(unsigned long *) &filter_stack_data
[ref
->offset
];
563 *(const char **) (&filter_stack_data
[ref
->offset
564 + sizeof(unsigned long)]);
565 if (unlikely(!reg
[insn
->reg
].str
)) {
566 dbg_printf("Filter warning: loading a NULL sequence.\n");
570 reg
[insn
->reg
].type
= REG_STRING
;
571 reg
[insn
->reg
].literal
= 0;
572 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
576 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
578 struct load_op
*insn
= (struct load_op
*) pc
;
579 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
581 dbg_printf("load field ref offset %u type s64\n",
583 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
584 sizeof(struct literal_numeric
));
585 reg
[insn
->reg
].type
= REG_S64
;
586 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
587 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
591 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
593 struct load_op
*insn
= (struct load_op
*) pc
;
594 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
596 dbg_printf("load field ref offset %u type double\n",
598 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
599 sizeof(struct literal_double
));
600 reg
[insn
->reg
].type
= REG_DOUBLE
;
601 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
602 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
606 OP(FILTER_OP_LOAD_STRING
):
608 struct load_op
*insn
= (struct load_op
*) pc
;
610 dbg_printf("load string %s\n", insn
->data
);
611 reg
[insn
->reg
].str
= insn
->data
;
612 reg
[insn
->reg
].type
= REG_STRING
;
613 reg
[insn
->reg
].seq_len
= UINT_MAX
;
614 reg
[insn
->reg
].literal
= 1;
615 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
619 OP(FILTER_OP_LOAD_S64
):
621 struct load_op
*insn
= (struct load_op
*) pc
;
623 memcpy(®
[insn
->reg
].v
, insn
->data
,
624 sizeof(struct literal_numeric
));
625 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
626 reg
[insn
->reg
].type
= REG_S64
;
627 next_pc
+= sizeof(struct load_op
)
628 + sizeof(struct literal_numeric
);
632 OP(FILTER_OP_LOAD_DOUBLE
):
634 struct load_op
*insn
= (struct load_op
*) pc
;
636 memcpy(®
[insn
->reg
].d
, insn
->data
,
637 sizeof(struct literal_double
));
638 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
639 reg
[insn
->reg
].type
= REG_DOUBLE
;
640 next_pc
+= sizeof(struct load_op
)
641 + sizeof(struct literal_double
);
646 OP(FILTER_OP_CAST_TO_S64
):
647 ERR("unsupported non-specialized bytecode op %u\n",
648 (unsigned int) *(filter_opcode_t
*) pc
);
652 OP(FILTER_OP_CAST_DOUBLE_TO_S64
):
654 struct cast_op
*insn
= (struct cast_op
*) pc
;
656 reg
[insn
->reg
].v
= (int64_t) reg
[insn
->reg
].d
;
657 reg
[insn
->reg
].type
= REG_S64
;
658 next_pc
+= sizeof(struct cast_op
);
662 OP(FILTER_OP_CAST_NOP
):
664 next_pc
+= sizeof(struct cast_op
);
670 /* return 0 (discard) on error */