From 5eaf717cfe47db882899a4e3d63b706c3a21c2ee Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Mon, 26 Aug 2013 12:50:43 +0200 Subject: [PATCH] support in &=, ^=, |=; support ~vector --- fold.c | 20 ++++++++++++++++++-- parser.c | 25 ++++++++++++++++++------- tests/bitnot.qc | 3 +++ tests/bitnot.tmpl | 1 + 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/fold.c b/fold.c index 714ca7b..4019794 100644 --- a/fold.c +++ b/fold.c @@ -121,6 +121,14 @@ static GMQCC_INLINE vec3_t vec3_xorvf(vec3_t a, qcfloat_t b) { return out; } +static GMQCC_INLINE vec3_t vec3_not(vec3_t a) { + vec3_t out; + out.x = (qcfloat_t)(~((qcint_t)a.x)); + out.y = (qcfloat_t)(~((qcint_t)a.y)); + out.z = (qcfloat_t)(~((qcint_t)a.z)); + return out; +} + static GMQCC_INLINE qcfloat_t vec3_mulvv(vec3_t a, vec3_t b) { return (a.x * b.x + a.y * b.y + a.z * b.z); } @@ -216,6 +224,7 @@ fold_t *fold_init(parser_t *parser) { (void)fold_constgen_float (fold, -1.0f); (void)fold_constgen_vector(fold, vec3_create(0.0f, 0.0f, 0.0f)); + (void)fold_constgen_vector(fold, vec3_create(-1.0f, -1.0f, -1.0f)); return fold; } @@ -589,8 +598,15 @@ static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_ } static GMQCC_INLINE ast_expression *fold_op_bnot(fold_t *fold, ast_value *a) { - if (fold_can_1(a)) - return fold_constgen_float(fold, ~((qcint_t)fold_immvalue_float(a))); + if (isfloat(a)) { + if (fold_can_1(a)) + return fold_constgen_float(fold, ~((qcint_t)fold_immvalue_float(a))); + } else { + if (isvector(a)) { + if (fold_can_1(a)) + return fold_constgen_vector(fold, vec3_not(fold_immvalue_vector(a))); + } + } return NULL; } diff --git a/parser.c b/parser.c index 1d94e92..0476820 100644 --- a/parser.c +++ b/parser.c @@ -1028,7 +1028,8 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) break; case opid2('&','='): case opid2('|','='): - if (NotSameType(TYPE_FLOAT)) { + case opid2('^','='): + if (NotSameType(TYPE_FLOAT) && NotSameType(TYPE_VECTOR)) { ast_type_to_string(exprs[0], ty1, sizeof(ty1)); ast_type_to_string(exprs[1], ty2, sizeof(ty2)); compile_error(ctx, "invalid types used in expression: %s and %s", @@ -1042,9 +1043,14 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) assignop = type_storep_instr[exprs[0]->vtype]; else assignop = type_store_instr[exprs[0]->vtype]; - out = (ast_expression*)ast_binstore_new(ctx, assignop, - (op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR), - exprs[0], exprs[1]); + if (exprs[0]->vtype == TYPE_FLOAT) + out = (ast_expression*)ast_binstore_new(ctx, assignop, + (op->id == opid2('^','=') ? VINSTR_BITXOR : op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR), + exprs[0], exprs[1]); + else + out = (ast_expression*)ast_binstore_new(ctx, assignop, + (op->id == opid2('^','=') ? VINSTR_BITXOR_V : op->id == opid2('&','=') ? VINSTR_BITAND_V : VINSTR_BITOR_V), + exprs[0], exprs[1]); break; case opid3('&','~','='): /* This is like: a &= ~(b); @@ -1074,13 +1080,18 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) break; case opid2('~', 'P'): - if (exprs[0]->vtype != TYPE_FLOAT) { + if (exprs[0]->vtype != TYPE_FLOAT && exprs[0]->vtype != TYPE_VECTOR) { ast_type_to_string(exprs[0], ty1, sizeof(ty1)); compile_error(ast_ctx(exprs[0]), "invalid type for bit not: %s", ty1); return false; } - if (!(out = fold_op(parser->fold, op, exprs))) - out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser->fold->imm_float[2], exprs[0]); + if (!(out = fold_op(parser->fold, op, exprs))) { + if (exprs[0]->vtype == TYPE_FLOAT) { + out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser->fold->imm_float[2], exprs[0]); + } else { + out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, (ast_expression*)parser->fold->imm_vector[1], exprs[0]); + } + } break; } #undef NotSameType diff --git a/tests/bitnot.qc b/tests/bitnot.qc index c6e875d..75834ba 100644 --- a/tests/bitnot.qc +++ b/tests/bitnot.qc @@ -3,12 +3,15 @@ void main() { float b; b = 1; float c; c = 1; float d; d = 1; + vector e; e = '1 1 1'; a &~= 1; // 0 b &= ~1; // 0 c &= ~d; // 0 + e &= ~e; // '0 0 0' print("a: ", ftos(a), "\nb: ", ftos(b), "\nc: ", ftos(c), "\n"); + print("e: ", vtos(e), "\n"); } diff --git a/tests/bitnot.tmpl b/tests/bitnot.tmpl index 75ae64a..132b040 100644 --- a/tests/bitnot.tmpl +++ b/tests/bitnot.tmpl @@ -7,3 +7,4 @@ E: $null M: a: 0 M: b: 0 M: c: 0 +M: e: '0 0 0' -- 2.39.2