Ejemplo n.º 1
0
static GMQCC_INLINE ast_expression *fold_op_mul(fold_t *fold, ast_value *a, ast_value *b) {
    if (isfloat(a)) {
        if (isvector(b)) {
            if (fold_can_2(a, b))
                return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(b), fold_immvalue_float(a)));
        } else {
            if (fold_can_2(a, b))
                return fold_constgen_float(fold, fold_immvalue_float(a) * fold_immvalue_float(b));
        }
    } else if (isvector(a)) {
        if (isfloat(b)) {
            if (fold_can_2(a, b))
                return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(a), fold_immvalue_float(b)));
        } else {
            if (fold_can_2(a, b)) {
                return fold_constgen_float(fold, vec3_mulvv(fold_immvalue_vector(a), fold_immvalue_vector(b)));
            } else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && fold_can_1(a)) {
                ast_expression *out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(a), b, "xyz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(a), b, "yxz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(a), b, "zxy"))) return out;
            } else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && fold_can_1(b)) {
                ast_expression *out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(b), a, "xyz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(b), a, "yxz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(b), a, "zxy"))) return out;
            }
        }
    }
    return NULL;
}
Ejemplo n.º 2
0
uint32_t code_genstring(code_t *code, const char *str) {
    size_t            hash;
    code_hash_entry_t existing;

    if (!str)
        return 0;

    if (!*str) {
        if (!code->string_cached_empty) {
            code->string_cached_empty = vec_size(code->chars);
            vec_push(code->chars, 0);
        }
        return code->string_cached_empty;
    }

    if (OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS)) {
        hash                      = ((unsigned char*)str)[strlen(str)-1];
        CODE_HASH_ENTER(existing) = code_util_str_htgeth(code->string_cache, str, hash);
    } else {
        hash                      = util_hthash(code->string_cache, str);
        CODE_HASH_ENTER(existing) = util_htgeth(code->string_cache, str, hash);
    }

    if (CODE_HASH_ENTER(existing))
        return CODE_HASH_LEAVE(existing);

    CODE_HASH_LEAVE(existing) = vec_size(code->chars);
    vec_append(code->chars, strlen(str)+1, str);

    util_htseth(code->string_cache, str, hash, CODE_HASH_ENTER(existing));
    return CODE_HASH_LEAVE(existing);
}
Ejemplo n.º 3
0
code_t *code_init() {
    static lex_ctx_t                empty_ctx       = {0, 0, 0};
    static prog_section_function_t  empty_function  = {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0}};
    static prog_section_statement_t empty_statement = {0,{0},{0},{0}};
    static prog_section_def_t       empty_def       = {0, 0, 0};

    code_t *code       = (code_t*)mem_a(sizeof(code_t));
    int     i          = 0;

    memset(code, 0, sizeof(code_t));
    code->entfields    = 0;
    code->string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024);

    /*
     * The way progs.dat is suppose to work is odd, there needs to be
     * some null (empty) statements, functions, and 28 globals
     */
    for(; i < 28; i++)
        vec_push(code->globals, 0);

    vec_push(code->chars, '\0');
    vec_push(code->functions,  empty_function);

    code_push_statement(code, &empty_statement, empty_ctx);

    vec_push(code->defs,    empty_def);
    vec_push(code->fields,  empty_def);

    return code;
}
Ejemplo n.º 4
0
static GMQCC_INLINE int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
    if (isfloat(condval) && fold_can_1(condval) && OPTS_OPTIMIZATION(OPTIM_CONST_FOLD_DCE)) {
        ast_expression_codegen *cgen;
        ir_block               *elide;
        ir_value               *dummy;
        bool                    istrue  = (fold_immvalue_float(condval) != 0.0f && branch->on_true);
        bool                    isfalse = (fold_immvalue_float(condval) == 0.0f && branch->on_false);
        ast_expression         *path    = (istrue)  ? branch->on_true  :
                                          (isfalse) ? branch->on_false : NULL;
        if (!path) {
            /*
             * no path to take implies that the evaluation is if(0) and there
             * is no else block. so eliminate all the code.
             */
            ++opts_optimizationcount[OPTIM_CONST_FOLD_DCE];
            return true;
        }

        if (!(elide = ir_function_create_block(ast_ctx(branch), func->ir_func, ast_function_label(func, ((istrue) ? "ontrue" : "onfalse")))))
            return false;
        if (!(*(cgen = path->codegen))((ast_expression*)path, func, false, &dummy))
            return false;
        if (!ir_block_create_jump(func->curblock, ast_ctx(branch), elide))
            return false;
        /*
         * now the branch has been eliminated and the correct block for the constant evaluation
         * is expanded into the current block for the function.
         */
        func->curblock = elide;
        ++opts_optimizationcount[OPTIM_CONST_FOLD_DCE];
        return true;
    }
    return -1; /* nothing done */
}
Ejemplo n.º 5
0
code_t::code_t()
{
    static lex_ctx_t                empty_ctx       = {0, 0, 0};
    static prog_section_function_t  empty_function  = {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0}};
    static prog_section_statement_t empty_statement = {0,{0},{0},{0}};
    static prog_section_def_t       empty_def       = {0, 0, 0};

    string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024);

    // The way progs.dat is suppose to work is odd, there needs to be
    // some null (empty) statements, functions, and 28 globals
    globals.insert(globals.begin(), 28, 0);

    chars.push_back('\0');
    functions.push_back(empty_function);

    code_push_statement(this, &empty_statement, empty_ctx);

    defs.push_back(empty_def);
    fields.push_back(empty_def);
}