mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 18:51:24 +00:00
Make unary - operator act as an ast_unary node. This allows for consistency (no sense in making unary use binstore nodes, it doesn't make much sense). It also allows for the peephole optimization on unary chains that cancel each other to take place; i.e code like "-(-a)" simplifies to "a", thus eliminating instructions.
This commit is contained in:
parent
3c931ecbf1
commit
b10de1b240
4 changed files with 33 additions and 25 deletions
9
ast.c
9
ast.c
|
@ -515,7 +515,7 @@ ast_unary* ast_unary_new(lex_ctx_t ctx, int op,
|
|||
ast_instantiate(ast_unary, ctx, ast_unary_delete);
|
||||
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_unary_codegen);
|
||||
|
||||
self->op = op;
|
||||
self->op = op;
|
||||
self->operand = expr;
|
||||
|
||||
if (ast_istype(expr, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
|
||||
|
@ -530,10 +530,13 @@ ast_unary* ast_unary_new(lex_ctx_t ctx, int op,
|
|||
|
||||
ast_propagate_effects(self, expr);
|
||||
|
||||
if (op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) {
|
||||
if (op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) {
|
||||
self->expression.vtype = TYPE_FLOAT;
|
||||
} else
|
||||
} else if (op >= VINSTR_NEG_F && op <= VINSTR_NEG_V) {
|
||||
self->expression.vtype = TYPE_FLOAT;
|
||||
} else {
|
||||
compile_error(ctx, "cannot determine type of unary operation %s", util_instr_str[op]);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
5
gmqcc.h
5
gmqcc.h
|
@ -712,6 +712,7 @@ enum {
|
|||
VINSTR_PHI,
|
||||
VINSTR_JUMP,
|
||||
VINSTR_COND,
|
||||
|
||||
/* A never returning CALL.
|
||||
* Creating this causes IR blocks to be marked as 'final'.
|
||||
* No-Return-Call
|
||||
|
@ -726,7 +727,9 @@ enum {
|
|||
VINSTR_BITXOR,
|
||||
VINSTR_BITXOR_V,
|
||||
VINSTR_BITXOR_VF,
|
||||
VINSTR_CROSS
|
||||
VINSTR_CROSS,
|
||||
VINSTR_NEG_F,
|
||||
VINSTR_NEG_V
|
||||
};
|
||||
|
||||
/* TODO: elide */
|
||||
|
|
20
ir.c
20
ir.c
|
@ -1878,16 +1878,22 @@ ir_value* ir_block_create_unary(ir_block *self, lex_ctx_t ctx,
|
|||
case INSTR_NOT_V:
|
||||
case INSTR_NOT_S:
|
||||
case INSTR_NOT_ENT:
|
||||
case INSTR_NOT_FNC:
|
||||
#if 0
|
||||
case INSTR_NOT_I:
|
||||
#endif
|
||||
case INSTR_NOT_FNC: /*
|
||||
case INSTR_NOT_I: */
|
||||
ot = TYPE_FLOAT;
|
||||
break;
|
||||
/* QC doesn't have other unary operations. We expect extensions to fill
|
||||
* the above list, otherwise we assume out-type = in-type, eg for an
|
||||
* unary minus
|
||||
|
||||
/*
|
||||
* Negation for virtual instructions is emulated with 0-value. Thankfully
|
||||
* the operand for 0 already exists so we just source it from here.
|
||||
*/
|
||||
case VINSTR_NEG_F:
|
||||
return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_F, NULL, operand, ot);
|
||||
break;
|
||||
case VINSTR_NEG_V:
|
||||
return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, NULL, operand, ot);
|
||||
break;
|
||||
|
||||
default:
|
||||
ot = operand->vtype;
|
||||
break;
|
||||
|
|
24
parser.c
24
parser.c
|
@ -466,22 +466,18 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
break;
|
||||
case opid2('-','P'):
|
||||
if (!(out = fold_op(parser->fold, op, exprs))) {
|
||||
switch (exprs[0]->vtype) {
|
||||
case TYPE_FLOAT:
|
||||
out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
|
||||
(ast_expression*)parser->fold->imm_float[0],
|
||||
exprs[0]);
|
||||
break;
|
||||
case TYPE_VECTOR:
|
||||
out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
|
||||
(ast_expression*)parser->fold->imm_vector[0],
|
||||
exprs[0]);
|
||||
break;
|
||||
default:
|
||||
compile_error(ctx, "invalid types used in expression: cannot negate type %s",
|
||||
type_name[exprs[0]->vtype]);
|
||||
if (exprs[0]->vtype != TYPE_FLOAT &&
|
||||
exprs[0]->vtype != TYPE_VECTOR) {
|
||||
compile_error(ctx, "invalid types used in unary expression: cannot negate type %s",
|
||||
type_name[exprs[0]->vtype]);
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* TYPE_VECTOR = TYPE_FLOAT+1,
|
||||
* VINSTR_NEG_V = VINSTR_NEG_F+1,
|
||||
* thus (VINSTR_NEG_F-TYPE_FLOAT) + TYPE_* = VINSTR_NEG_*.
|
||||
*/
|
||||
out = (ast_expression*)ast_unary_new(ctx, (VINSTR_NEG_F-TYPE_FLOAT) + exprs[0]->vtype, exprs[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in a new issue