#define MVM_JIT_PTR_SZ sizeof(void*) #define MVM_JIT_REG_SZ sizeof(MVMRegister) #define MVM_JIT_INT_SZ sizeof(MVMint64) #define MVM_JIT_NUM_SZ sizeof(MVMnum64) /* C argument types */ enum { MVM_JIT_PTR, MVM_JIT_INT, MVM_JIT_NUM }; #include "expr_ops.h" enum MVMJitExprOperator { #define MVM_JIT_OP_ENUM(name, nchild, narg) MVM_JIT_##name MVM_JIT_EXPR_OPS(MVM_JIT_OP_ENUM) #undef MVM_JIT_OP_ENUM }; /* samcv++ for this trick */ #define MVM_STATIC_ASSERT(x) typedef char __ASSERT[(x)?1:-1] /* Tree node information for easy access and use during compilation (a symbol table entry of sorts) */ struct MVMJitExprInfo { MVMuint8 num_links; MVMuint8 num_args; /* VM 'register' type represented by this node */ MVMint8 type; /* Size of computed value */ MVMuint8 size; }; MVM_STATIC_ASSERT(sizeof(MVMJitExprInfo) <= sizeof(MVMint32)); struct MVMJitExprTree { MVMJitGraph *graph; MVM_VECTOR_DECL(MVMint32, nodes); MVM_VECTOR_DECL(MVMint32, roots); MVM_VECTOR_DECL(union { MVMint64 i; MVMnum64 n; const void *p; uintptr_t u; }, constants); MVMuint32 seq_nr; }; struct MVMJitExprTemplate { const MVMint32 *code; const char *info; MVMint32 len; MVMint32 root; MVMint32 flags; }; #define MVM_JIT_EXPR_TEMPLATE_VALUE 0 #define MVM_JIT_EXPR_TEMPLATE_DESTRUCTIVE 1 struct MVMJitTreeTraverser { void (*preorder)(MVMThreadContext *tc, MVMJitTreeTraverser *traverser, MVMJitExprTree *tree, MVMint32 node); void (*inorder)(MVMThreadContext *tc, MVMJitTreeTraverser *traverser, MVMJitExprTree *tree, MVMint32 node, MVMint32 child); void (*postorder)(MVMThreadContext *tc, MVMJitTreeTraverser *traverser, MVMJitExprTree *tree, MVMint32 node); void *data; MVM_VECTOR_DECL(MVMint32, visits); enum { MVM_JIT_TRAVERSER_REPEAT, MVM_JIT_TRAVERSER_ONCE } policy; }; /* properties of expression ops */ enum MVMJitExprOperator MVM_jit_expr_op_invert_comparison(enum MVMJitExprOperator op); MVMint32 MVM_jit_expr_op_is_binary(enum MVMJitExprOperator op); MVMint32 MVM_jit_expr_op_is_unary(enum MVMJitExprOperator op); MVMint32 MVM_jit_expr_op_is_commutative(enum MVMJitExprOperator op); MVMint32 MVM_jit_expr_op_is_call(enum MVMJitExprOperator op); const char * MVM_jit_expr_operator_name(MVMThreadContext *tc, enum MVMJitExprOperator operator); MVMJitExprTree * MVM_jit_expr_tree_build(MVMThreadContext *tc, MVMJitGraph *jg, MVMSpeshIterator *iter); MVMint32 MVM_jit_expr_apply_template(MVMThreadContext *tc, MVMJitExprTree *tree, const MVMJitExprTemplate*, MVMint32 *operands); MVMint32 MVM_jit_expr_apply_template_adhoc(MVMThreadContext *tc, MVMJitExprTree *tree, char *template, ...); void MVM_jit_expr_tree_traverse(MVMThreadContext *tc, MVMJitExprTree *tree, MVMJitTreeTraverser *traverser); void MVM_jit_expr_tree_destroy(MVMThreadContext *tc, MVMJitExprTree *tree); MVMint32 MVM_jit_expr_tree_get_nodes(MVMThreadContext *tc, MVMJitExprTree *tree, MVMint32 node, const char *path, MVMint32 *buffer); MVM_STATIC_INLINE MVMJitExprInfo * MVM_JIT_EXPR_INFO(MVMJitExprTree *tree, MVMint32 node) { return (MVMJitExprInfo*)(tree->nodes + node + 1); } MVM_STATIC_INLINE MVMuint8 MVM_JIT_EXPR_NCHILD(MVMJitExprTree *tree, MVMint32 node) { return MVM_JIT_EXPR_INFO(tree, node)->num_links; } MVM_STATIC_INLINE MVMuint8 MVM_JIT_EXPR_TYPE(MVMJitExprTree *tree, MVMint32 node) { return MVM_JIT_EXPR_INFO(tree, node)->type; } MVM_STATIC_INLINE MVMint32 MVM_JIT_EXPR_FIRST_CHILD(MVMJitExprTree *tree, MVMint32 node) { return node + 2; } MVM_STATIC_INLINE MVMint32 * MVM_JIT_EXPR_LINKS(MVMJitExprTree *tree, MVMint32 node) { return tree->nodes + MVM_JIT_EXPR_FIRST_CHILD(tree, node); } MVM_STATIC_INLINE MVMint32 * MVM_JIT_EXPR_ARGS(MVMJitExprTree *tree, MVMint32 node) { return MVM_JIT_EXPR_LINKS(tree, node) + MVM_JIT_EXPR_NCHILD(tree, node); } MVM_STATIC_INLINE MVMint32 MVM_JIT_EXPR_IS_NUM(MVMJitExprTree *tree, MVMint32 node) { MVMuint8 expr_type = MVM_JIT_EXPR_TYPE(tree,node); return expr_type == MVM_reg_num32 || expr_type == MVM_reg_num64; }