#endif
+#define IS_INTEGER_REGISTER(reg_type) \
+ (reg_type == REG_U64 || reg_type == REG_S64)
+
static int context_get_index(struct lttng_ctx *ctx,
struct load_ptr *ptr,
uint32_t idx)
case OBJECT_TYPE_U8:
dbg_printf("op load field u8\n");
stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr;
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
break;
case OBJECT_TYPE_U16:
{
if (stack_top->u.ptr.rev_bo)
tmp = bswap_16(tmp);
stack_top->u.v = tmp;
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
break;
}
case OBJECT_TYPE_U32:
if (stack_top->u.ptr.rev_bo)
tmp = bswap_32(tmp);
stack_top->u.v = tmp;
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
break;
}
case OBJECT_TYPE_U64:
if (stack_top->u.ptr.rev_bo)
tmp = bswap_64(tmp);
stack_top->u.v = tmp;
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
break;
}
case OBJECT_TYPE_DOUBLE:
/* Handle dynamic typing. */
switch (estack_ax_t) {
case REG_S64:
+ case REG_U64:
retval = !!estack_ax_v;
break;
case REG_DOUBLE:
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_EQ_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_EQ_DOUBLE_S64);
break;
case REG_DOUBLE:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_EQ_S64_DOUBLE);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_EQ_DOUBLE);
case REG_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64: /* Fall-through */
case REG_DOUBLE:
ret = -EINVAL;
goto end;
case REG_STAR_GLOB_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64: /* Fall-through */
case REG_DOUBLE:
ret = -EINVAL;
goto end;
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_NE_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_NE_DOUBLE_S64);
break;
case REG_DOUBLE:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_NE_S64_DOUBLE);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_NE_DOUBLE);
case REG_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64:
case REG_DOUBLE:
ret = -EINVAL;
goto end;
case REG_STAR_GLOB_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64:
case REG_DOUBLE:
ret = -EINVAL;
goto end;
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_GT_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_GT_DOUBLE_S64);
break;
case REG_DOUBLE:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_GT_S64_DOUBLE);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_GT_DOUBLE);
case REG_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64: /* Fall-through */
case REG_DOUBLE: /* Fall-through */
case REG_STAR_GLOB_STRING:
ret = -EINVAL;
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_LT_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_LT_DOUBLE_S64);
break;
case REG_DOUBLE:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_LT_S64_DOUBLE);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_LT_DOUBLE);
case REG_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64: /* Fall-through */
case REG_DOUBLE: /* Fall-through */
case REG_STAR_GLOB_STRING:
ret = -EINVAL;
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_GE_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_GE_DOUBLE_S64);
break;
case REG_DOUBLE:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_GE_S64_DOUBLE);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_GE_DOUBLE);
case REG_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64: /* Fall-through */
case REG_DOUBLE: /* Fall-through */
case REG_STAR_GLOB_STRING:
ret = -EINVAL;
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_LE_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_LE_DOUBLE_S64);
break;
case REG_DOUBLE:
switch (estack_bx_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through */
+ case REG_U64:
JUMP_TO(FILTER_OP_LE_S64_DOUBLE);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_LE_DOUBLE);
case REG_STRING:
switch (estack_bx_t) {
case REG_S64: /* Fall-through */
+ case REG_U64: /* Fall-through */
case REG_DOUBLE: /* Fall-through */
case REG_STAR_GLOB_STRING:
ret = -EINVAL;
{
int64_t res;
- /* Dynamic typing. */
- if (estack_ax_t != REG_S64 || estack_bx_t != REG_S64) {
+ if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
ret = -EINVAL;
goto end;
}
+
/* Catch undefined behavior. */
if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
ret = -EINVAL;
res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
estack_pop(stack, top, ax, bx, ax_t, bx_t);
estack_ax_v = res;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct binary_op);
PO;
}
{
int64_t res;
- /* Dynamic typing. */
- if (estack_ax_t != REG_S64 || estack_bx_t != REG_S64) {
+ if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
ret = -EINVAL;
goto end;
}
+
/* Catch undefined behavior. */
if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
ret = -EINVAL;
res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
estack_pop(stack, top, ax, bx, ax_t, bx_t);
estack_ax_v = res;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct binary_op);
PO;
}
{
int64_t res;
- /* Dynamic typing. */
- if (estack_ax_t != REG_S64 || estack_bx_t != REG_S64) {
+ if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
ret = -EINVAL;
goto end;
}
res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
estack_pop(stack, top, ax, bx, ax_t, bx_t);
estack_ax_v = res;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct binary_op);
PO;
}
{
int64_t res;
- /* Dynamic typing. */
- if (estack_ax_t != REG_S64 || estack_bx_t != REG_S64) {
+ if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
ret = -EINVAL;
goto end;
}
res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
estack_pop(stack, top, ax, bx, ax_t, bx_t);
estack_ax_v = res;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct binary_op);
PO;
}
{
int64_t res;
- /* Dynamic typing. */
- if (estack_ax_t != REG_S64 || estack_bx_t != REG_S64) {
+ if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
ret = -EINVAL;
goto end;
}
res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
estack_pop(stack, top, ax, bx, ax_t, bx_t);
estack_ax_v = res;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct binary_op);
PO;
}
/* Dynamic typing. */
switch (estack_ax_t) {
case REG_S64: /* Fall-through. */
+ case REG_U64:
JUMP_TO(FILTER_OP_UNARY_PLUS_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_UNARY_PLUS_DOUBLE);
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through. */
+ case REG_U64:
JUMP_TO(FILTER_OP_UNARY_MINUS_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_UNARY_MINUS_DOUBLE);
{
/* Dynamic typing. */
switch (estack_ax_t) {
- case REG_S64:
+ case REG_S64: /* Fall-through. */
+ case REG_U64:
JUMP_TO(FILTER_OP_UNARY_NOT_S64);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_UNARY_NOT_DOUBLE);
OP(FILTER_OP_UNARY_BIT_NOT):
{
/* Dynamic typing. */
- if (estack_ax_t != REG_S64) {
+ if (!IS_INTEGER_REGISTER(estack_ax_t)) {
ret = -EINVAL;
goto end;
}
estack_ax_v = ~(uint64_t) estack_ax_v;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct unary_op);
PO;
}
OP(FILTER_OP_UNARY_NOT_S64):
{
estack_ax_v = !estack_ax_v;
+ estack_ax_t = REG_S64;
next_pc += sizeof(struct unary_op);
PO;
}
{
struct logical_op *insn = (struct logical_op *) pc;
- if (estack_ax_t != REG_S64) {
+ if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
ret = -EINVAL;
goto end;
}
{
struct logical_op *insn = (struct logical_op *) pc;
- if (estack_ax_t != REG_S64) {
+ if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
ret = -EINVAL;
goto end;
}
JUMP_TO(FILTER_OP_CAST_NOP);
case REG_DOUBLE:
JUMP_TO(FILTER_OP_CAST_DOUBLE_TO_S64);
+ case REG_U64:
+ estack_ax_t = REG_S64;
+ next_pc += sizeof(struct cast_op);
case REG_STRING: /* Fall-through */
case REG_STAR_GLOB_STRING:
ret = -EINVAL;
dbg_printf("op load field u8\n");
estack_ax_v = *(uint8_t *) estack_ax(stack, top)->u.ptr.ptr;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct load_op);
PO;
}
dbg_printf("op load field u16\n");
estack_ax_v = *(uint16_t *) estack_ax(stack, top)->u.ptr.ptr;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct load_op);
PO;
}
dbg_printf("op load field u32\n");
estack_ax_v = *(uint32_t *) estack_ax(stack, top)->u.ptr.ptr;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct load_op);
PO;
}
dbg_printf("op load field u64\n");
estack_ax_v = *(uint64_t *) estack_ax(stack, top)->u.ptr.ptr;
- estack_ax_t = REG_S64;
+ estack_ax_t = REG_U64;
next_pc += sizeof(struct load_op);
PO;
}
break;
case OBJECT_TYPE_U8:
dbg_printf("op load field u8\n");
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
insn->op = FILTER_OP_LOAD_FIELD_U8;
break;
case OBJECT_TYPE_U16:
dbg_printf("op load field u16\n");
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
if (!stack_top->load.rev_bo)
insn->op = FILTER_OP_LOAD_FIELD_U16;
break;
case OBJECT_TYPE_U32:
dbg_printf("op load field u32\n");
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
if (!stack_top->load.rev_bo)
insn->op = FILTER_OP_LOAD_FIELD_U32;
break;
case OBJECT_TYPE_U64:
dbg_printf("op load field u64\n");
- stack_top->type = REG_S64;
+ stack_top->type = REG_U64;
if (!stack_top->load.rev_bo)
insn->op = FILTER_OP_LOAD_FIELD_U64;
break;
struct vstack_load *load, bool is_context)
{
load->type = LOAD_OBJECT;
- /*
- * LTTng-UST layout all integer fields as s64 on the stack for the filter.
- */
+
switch (field->type.atype) {
case atype_integer:
if (field->type.u.integer.signedness)
goto end;
case FILTER_OP_RETURN:
- if (vstack_ax(stack)->type == REG_S64)
+ if (vstack_ax(stack)->type == REG_S64 ||
+ vstack_ax(stack)->type == REG_U64)
*(filter_opcode_t *) pc = FILTER_OP_RETURN_S64;
ret = 0;
goto end;
case FILTER_OP_RETURN_S64:
- if (vstack_ax(stack)->type != REG_S64) {
+ if (vstack_ax(stack)->type != REG_S64 &&
+ vstack_ax(stack)->type != REG_U64) {
ERR("Unexpected register type\n");
ret = -EINVAL;
goto end;
insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
break;
case REG_S64:
+ case REG_U64:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_EQ_S64;
else
insn->op = FILTER_OP_EQ_DOUBLE_S64;
case REG_DOUBLE:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_EQ_S64_DOUBLE;
else
insn->op = FILTER_OP_EQ_DOUBLE;
insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
break;
case REG_S64:
+ case REG_U64:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_NE_S64;
else
insn->op = FILTER_OP_NE_DOUBLE_S64;
case REG_DOUBLE:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_NE_S64_DOUBLE;
else
insn->op = FILTER_OP_NE_DOUBLE;
insn->op = FILTER_OP_GT_STRING;
break;
case REG_S64:
+ case REG_U64:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_GT_S64;
else
insn->op = FILTER_OP_GT_DOUBLE_S64;
case REG_DOUBLE:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_GT_S64_DOUBLE;
else
insn->op = FILTER_OP_GT_DOUBLE;
insn->op = FILTER_OP_LT_STRING;
break;
case REG_S64:
+ case REG_U64:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_LT_S64;
else
insn->op = FILTER_OP_LT_DOUBLE_S64;
case REG_DOUBLE:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_LT_S64_DOUBLE;
else
insn->op = FILTER_OP_LT_DOUBLE;
insn->op = FILTER_OP_GE_STRING;
break;
case REG_S64:
+ case REG_U64:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_GE_S64;
else
insn->op = FILTER_OP_GE_DOUBLE_S64;
case REG_DOUBLE:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_GE_S64_DOUBLE;
else
insn->op = FILTER_OP_GE_DOUBLE;
ret = -EINVAL;
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct binary_op);
break;
}
insn->op = FILTER_OP_LE_STRING;
break;
case REG_S64:
+ case REG_U64:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_LE_S64;
else
insn->op = FILTER_OP_LE_DOUBLE_S64;
case REG_DOUBLE:
if (vstack_bx(stack)->type == REG_UNKNOWN)
break;
- if (vstack_bx(stack)->type == REG_S64)
+ if (vstack_bx(stack)->type == REG_S64 ||
+ vstack_bx(stack)->type == REG_U64)
insn->op = FILTER_OP_LE_S64_DOUBLE;
else
insn->op = FILTER_OP_LE_DOUBLE;
case FILTER_OP_LT_S64_DOUBLE:
case FILTER_OP_GE_S64_DOUBLE:
case FILTER_OP_LE_S64_DOUBLE:
+ {
+ /* Pop 2, push 1 */
+ if (vstack_pop(stack)) {
+ ret = -EINVAL;
+ goto end;
+ }
+ vstack_ax(stack)->type = REG_S64;
+ next_pc += sizeof(struct binary_op);
+ break;
+ }
+
case FILTER_OP_BIT_RSHIFT:
case FILTER_OP_BIT_LSHIFT:
case FILTER_OP_BIT_AND:
goto end;
case REG_S64:
+ case REG_U64:
insn->op = FILTER_OP_UNARY_PLUS_S64;
break;
case REG_DOUBLE:
goto end;
case REG_S64:
+ case REG_U64:
insn->op = FILTER_OP_UNARY_MINUS_S64;
break;
case REG_DOUBLE:
goto end;
case REG_S64:
+ case REG_U64:
insn->op = FILTER_OP_UNARY_NOT_S64;
break;
case REG_DOUBLE:
insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
break;
case REG_UNKNOWN:
+ case REG_U64:
break;
}
/* Pop 1, push 1 */
case FILTER_OP_LOAD_FIELD_S16:
case FILTER_OP_LOAD_FIELD_S32:
case FILTER_OP_LOAD_FIELD_S64:
+ {
+ /* Pop 1, push 1 */
+ vstack_ax(stack)->type = REG_S64;
+ next_pc += sizeof(struct load_op);
+ break;
+ }
+
case FILTER_OP_LOAD_FIELD_U8:
case FILTER_OP_LOAD_FIELD_U16:
case FILTER_OP_LOAD_FIELD_U32:
case FILTER_OP_LOAD_FIELD_U64:
{
/* Pop 1, push 1 */
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct load_op);
break;
}
}
break;
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
goto error_mismatch;
}
break;
case REG_STAR_GLOB_STRING:
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
goto error_mismatch;
}
break;
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
switch (vstack_bx(stack)->type) {
default:
case REG_STAR_GLOB_STRING:
goto error_mismatch;
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
break;
}
case REG_UNKNOWN:
goto unknown;
case REG_S64:
+ case REG_U64:
switch (vstack_bx(stack)->type) {
default:
goto error_type;
case REG_UNKNOWN:
goto unknown;
case REG_S64:
+ case REG_U64:
break;
}
break;
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_S64
- || vstack_bx(stack)->type != REG_S64) {
+ switch (vstack_ax(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
+ ERR("Unexpected register type for s64 comparator\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_bx(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
ERR("Unexpected register type for s64 comparator\n");
ret = -EINVAL;
goto end;
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_S64 && vstack_bx(stack)->type != REG_DOUBLE) {
+ switch (vstack_ax(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
+ ERR("Double-S64 operator has unexpected register types\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_bx(stack)->type) {
+ case REG_DOUBLE:
+ break;
+ default:
ERR("Double-S64 operator has unexpected register types\n");
ret = -EINVAL;
goto end;
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64) {
+ switch (vstack_ax(stack)->type) {
+ case REG_DOUBLE:
+ break;
+ default:
+ ERR("S64-Double operator has unexpected register types\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_bx(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
ERR("S64-Double operator has unexpected register types\n");
ret = -EINVAL;
goto end;
goto end;
case REG_S64:
break;
+ case REG_U64:
+ break;
case REG_DOUBLE:
break;
case REG_UNKNOWN:
goto end;
case REG_S64:
break;
+ case REG_U64:
+ break;
case REG_UNKNOWN:
break;
}
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_S64) {
+ if (vstack_ax(stack)->type != REG_S64 &&
+ vstack_ax(stack)->type != REG_U64) {
ERR("Invalid register type\n");
ret = -EINVAL;
goto end;
goto end;
}
if (vstack_ax(stack)->type != REG_S64
+ && vstack_ax(stack)->type != REG_U64
&& vstack_ax(stack)->type != REG_UNKNOWN) {
- ERR("Logical comparator expects S64 or dynamic register\n");
+ ERR("Logical comparator expects S64, U64 or dynamic register\n");
ret = -EINVAL;
goto end;
}
goto end;
case REG_S64:
break;
+ case REG_U64:
+ break;
case REG_DOUBLE:
break;
case REG_UNKNOWN:
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
case REG_UNKNOWN:
break;
default:
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
break;
default:
case REG_UNKNOWN:
case FILTER_OP_LT_S64_DOUBLE:
case FILTER_OP_GE_S64_DOUBLE:
case FILTER_OP_LE_S64_DOUBLE:
+ {
+ /* Pop 2, push 1 */
+ if (vstack_pop(stack)) {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (!vstack_ax(stack)) {
+ ERR("Empty stack\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_ax(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ case REG_DOUBLE:
+ case REG_STRING:
+ case REG_STAR_GLOB_STRING:
+ case REG_UNKNOWN:
+ break;
+ default:
+ ERR("Unexpected register type %d for operation\n",
+ (int) vstack_ax(stack)->type);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ vstack_ax(stack)->type = REG_S64;
+ next_pc += sizeof(struct binary_op);
+ break;
+ }
+
case FILTER_OP_BIT_RSHIFT:
case FILTER_OP_BIT_LSHIFT:
case FILTER_OP_BIT_AND:
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
case REG_STRING:
case REG_STAR_GLOB_STRING:
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct binary_op);
break;
}
case REG_UNKNOWN:
case REG_DOUBLE:
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Unexpected register type %d for operation\n",
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Unexpected register type %d for operation\n",
goto end;
}
- vstack_ax(stack)->type = REG_S64;
next_pc += sizeof(struct unary_op);
break;
}
case REG_UNKNOWN:
case REG_DOUBLE:
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Unexpected register type %d for operation\n",
goto end;
}
- vstack_ax(stack)->type = REG_S64;
next_pc += sizeof(struct unary_op);
break;
}
switch (vstack_ax(stack)->type) {
case REG_UNKNOWN:
case REG_S64:
+ case REG_U64:
break;
case REG_DOUBLE:
default:
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct unary_op);
break;
}
/* There is always a cast-to-s64 operation before a or/and op. */
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Incorrect register type %d for operation\n",
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
case REG_UNKNOWN:
break;
case FILTER_OP_LOAD_FIELD_S16:
case FILTER_OP_LOAD_FIELD_S32:
case FILTER_OP_LOAD_FIELD_S64:
+ {
+ /* Pop 1, push 1 */
+ if (!vstack_ax(stack)) {
+ ERR("Empty stack\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ if (vstack_ax(stack)->type != REG_PTR) {
+ ERR("Expecting pointer on top of stack\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ vstack_ax(stack)->type = REG_S64;
+ next_pc += sizeof(struct load_op);
+ break;
+ }
+
case FILTER_OP_LOAD_FIELD_U8:
case FILTER_OP_LOAD_FIELD_U16:
case FILTER_OP_LOAD_FIELD_U32:
ret = -EINVAL;
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct load_op);
break;
}
enum entry_type {
REG_S64,
+ REG_U64,
REG_DOUBLE,
REG_STRING,
REG_STAR_GLOB_STRING,