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);
}
(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;
}
}
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;
}
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",
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);
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