fixed vector ops constant folding.

This commit is contained in:
Dale Weiler 2013-07-31 17:05:43 +00:00
parent d0ee56f25f
commit 5f2b7e3d57
2 changed files with 21 additions and 19 deletions

23
fold.c
View file

@ -323,7 +323,7 @@ static GMQCC_INLINE ast_expression *fold_op_mul_vec(fold_t *fold, vec3_t vec, as
out = (ast_expression*)ast_member_new(fold_ctx(fold), (ast_expression*)sel, set[0]-'x', NULL); out = (ast_expression*)ast_member_new(fold_ctx(fold), (ast_expression*)sel, set[0]-'x', NULL);
out->node.keep = false; out->node.keep = false;
((ast_member*)out)->rvalue = true; ((ast_member*)out)->rvalue = true;
if (!x != -1) if (x != -1)
return (ast_expression*)ast_binary_new(fold_ctx(fold), INSTR_MUL_F, fold_constgen_float(fold, x), out); return (ast_expression*)ast_binary_new(fold_ctx(fold), INSTR_MUL_F, fold_constgen_float(fold, x), out);
} }
return NULL; return NULL;
@ -416,8 +416,21 @@ static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_
} else if (isvector(a)) { } else if (isvector(a)) {
if (fold_can_2(a, b)) if (fold_can_2(a, b))
return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(a), 1.0f / fold_immvalue_float(b))); return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(a), 1.0f / fold_immvalue_float(b)));
else if (fold_can_1(b)) else {
return fold_constgen_float (fold, 1.0f / fold_immvalue_float(b)); return (ast_expression*)ast_binary_new(
fold_ctx(fold),
INSTR_MUL_VF,
(ast_expression*)a,
(fold_can_1(b))
? (ast_expression*)fold_constgen_float(fold, 1.0f / fold_immvalue_float(b))
: (ast_expression*)ast_binary_new(
fold_ctx(fold),
INSTR_DIV_F,
(ast_expression*)fold->imm_float[1],
(ast_expression*)b
)
);
}
} }
return NULL; return NULL;
} }
@ -478,8 +491,8 @@ static GMQCC_INLINE ast_expression *fold_op_andor(fold_t *fold, ast_value *a, as
fold, fold,
((or) ? (fold_immediate_true(fold, a) || fold_immediate_true(fold, b)) ((or) ? (fold_immediate_true(fold, a) || fold_immediate_true(fold, b))
: (fold_immediate_true(fold, a) && fold_immediate_true(fold, b))) : (fold_immediate_true(fold, a) && fold_immediate_true(fold, b)))
? 1.0f ? 1
: 0.0f : 0
); );
} }
} }

View file

@ -587,6 +587,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
} }
} }
break; break;
case opid1('/'): case opid1('/'):
if (exprs[1]->vtype != TYPE_FLOAT) { if (exprs[1]->vtype != TYPE_FLOAT) {
ast_type_to_string(exprs[0], ty1, sizeof(ty1)); ast_type_to_string(exprs[0], ty1, sizeof(ty1));
@ -595,21 +596,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
return false; return false;
} }
if (!(out = fold_op(parser->fold, op, exprs))) { if (!(out = fold_op(parser->fold, op, exprs))) {
if (exprs[0]->vtype == TYPE_FLOAT) if (exprs[0]->vtype == TYPE_FLOAT)
out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]); out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
else if (exprs[0]->vtype == TYPE_VECTOR) { else {
out = (ast_expression*)ast_binary_new (
ctx,
INSTR_MUL_VF,
exprs[0],
(ast_expression*)ast_binary_new(
ctx,
INSTR_DIV_F,
(ast_expression*)parser->fold->imm_float[1],
exprs[1]
)
);
} else {
ast_type_to_string(exprs[0], ty1, sizeof(ty1)); ast_type_to_string(exprs[0], ty1, sizeof(ty1));
ast_type_to_string(exprs[1], ty2, sizeof(ty2)); ast_type_to_string(exprs[1], ty2, sizeof(ty2));
compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2); compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2);