mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
[qfcc] Add more statement types for move/memset
They ease the statement checks between assign/move/memset and the pointer versions (don't need all those strcmps)
This commit is contained in:
parent
3c2f6c8447
commit
16bda66785
4 changed files with 40 additions and 13 deletions
|
@ -73,17 +73,20 @@ typedef struct operand_s {
|
|||
|
||||
Statement types are broken down into expressions (binary and unary,
|
||||
includes address and pointer dereferencing (read)), assignment, pointer
|
||||
assignment (write to dereference pointer), move (special case of pointer
|
||||
assignment), state, function related (call, rcall, return and done), and
|
||||
flow control (conditional branches, goto, jump (single pointer and jump
|
||||
table)).
|
||||
assignment (write to dereference pointer), move (special case of
|
||||
assignment), pointer move (special case of pointer assignment), state,
|
||||
function related (call, rcall, return and done), and flow control
|
||||
(conditional branches, goto, jump (single pointer and jump table)).
|
||||
*/
|
||||
typedef enum {
|
||||
st_none, ///< not a (valid) statement. Used in dags.
|
||||
st_expr, ///< c = a op b; or c = op a;
|
||||
st_assign, ///< b = a
|
||||
st_ptrassign, ///< *b = a; or *(b + c) = a;
|
||||
st_move, ///< memcpy (c, a, b);
|
||||
st_move, ///< memcpy (c, a, b); c and a are direct def references
|
||||
st_ptrmove, ///< memcpy (c, a, b); c and a are pointers
|
||||
st_memset, ///< memset (c, a, b); c is direct def reference
|
||||
st_ptrmemset, ///< memset (c, a, b); c is pointer
|
||||
st_state, ///< state (a, b); or state (a, b, c)
|
||||
st_func, ///< call, rcall or return/done
|
||||
st_flow, ///< if/ifa/ifae/ifb/ifbe/ifnot or goto or jump/jumpb
|
||||
|
|
|
@ -49,8 +49,10 @@
|
|||
|
||||
#include "dags.h"
|
||||
#include "diagnostic.h"
|
||||
#include "dot.h"
|
||||
#include "flow.h"
|
||||
#include "function.h"
|
||||
#include "options.h"
|
||||
#include "qfcc.h"
|
||||
#include "statements.h"
|
||||
#include "strpool.h"
|
||||
|
@ -133,6 +135,11 @@ daglabel_string (daglabel_t *label)
|
|||
// operand_string might use quote_string, which returns a pointer to
|
||||
// a static variable.
|
||||
dstring_copystr (str, operand_string (label->op));
|
||||
#if 0
|
||||
if (label->op->type) {
|
||||
dstring_appendstr (str, label->op->type->encoding);
|
||||
}
|
||||
#endif
|
||||
return quote_string (str->str);
|
||||
}
|
||||
|
||||
|
@ -730,10 +737,13 @@ dag_create (flownode_t *flownode)
|
|||
int i;
|
||||
|
||||
dag_make_children (dag, s, operands, children);
|
||||
if (s->type == st_flow || s->type == st_func)
|
||||
for (i = 0; i < 3; i++)
|
||||
if (children[i])
|
||||
if (s->type == st_flow || s->type == st_func) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (children[i]) {
|
||||
dag_make_var_live (live_vars, operands[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
op = opcode_label (dag, s->opcode, s->expr);
|
||||
n = children[0];
|
||||
if (s->type != st_assign
|
||||
|
@ -759,7 +769,12 @@ dag_create (flownode_t *flownode)
|
|||
labels = malloc (dag->num_labels * sizeof (daglabel_t *));
|
||||
memcpy (labels, dag->labels, dag->num_labels * sizeof (daglabel_t *));
|
||||
dag->labels = labels;
|
||||
|
||||
#if 0
|
||||
if (options.block_dot.dags) {
|
||||
flownode->dag = dag;
|
||||
dump_dot ("raw-dags", flownode->graph, dump_dot_flow_dags);
|
||||
}
|
||||
#endif
|
||||
dag_remove_dead_vars (dag, live_vars);
|
||||
dag_sort_nodes (dag);
|
||||
set_delete (live_vars);
|
||||
|
@ -972,6 +987,9 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
|||
dst = operands[0];
|
||||
break;
|
||||
case st_move:
|
||||
case st_ptrmove:
|
||||
case st_memset:
|
||||
case st_ptrmemset:
|
||||
if (!strcmp (dagnode->label->opcode, "<MOVE>")) {
|
||||
dst = generate_moves (dag, block, dagnode);
|
||||
break;
|
||||
|
|
|
@ -1116,6 +1116,9 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
|||
break;
|
||||
case st_ptrassign:
|
||||
case st_move:
|
||||
case st_ptrmove:
|
||||
case st_memset:
|
||||
case st_ptrmemset:
|
||||
flow_add_op_var (use, s->opa, 1);
|
||||
flow_add_op_var (use, s->opb, 1);
|
||||
if (!strcmp (s->opcode, "<MOVE>")
|
||||
|
|
|
@ -758,7 +758,7 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
|
|||
const char **opcode_set = opcode_sets[0];
|
||||
const char *opcode;
|
||||
int need_ptr = 0;
|
||||
//operand_t *dummy;
|
||||
st_type_t type = st_move;
|
||||
|
||||
if ((src && src->op_type == op_nil) || src_expr->type == ex_nil) {
|
||||
// switch to memset because nil is type agnostic 0 and structures
|
||||
|
@ -769,6 +769,7 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
|
|||
if (op) {
|
||||
*op = nil_operand (dst_type, src_expr);
|
||||
}
|
||||
type = st_memset;
|
||||
if (is_indirect (dst_expr)) {
|
||||
goto dereference_dst;
|
||||
}
|
||||
|
@ -815,9 +816,10 @@ dereference_dst:
|
|||
opcode = opcode_set[0];
|
||||
} else {
|
||||
opcode = opcode_set[1];
|
||||
type++; // from st_move/st_memset to st_ptrmove/st_ptrmemset
|
||||
}
|
||||
|
||||
s = new_statement (st_move, opcode, e);
|
||||
s = new_statement (type, opcode, e);
|
||||
s->opa = src;
|
||||
s->opb = size;
|
||||
s->opc = dst;
|
||||
|
@ -932,7 +934,8 @@ expr_move (sblock_t *sblock, expr_t *e, operand_t **op)
|
|||
dst = *op;
|
||||
sblock = statement_subexpr (sblock, src_expr, &src);
|
||||
sblock = statement_subexpr (sblock, size_expr, &size);
|
||||
s = new_statement (st_move, convert_op (e->e.expr.op), e);
|
||||
s = new_statement (e->e.expr.op == 'm' ? st_move : st_ptrmove,
|
||||
convert_op (e->e.expr.op), e);
|
||||
s->opa = src;
|
||||
s->opb = size;
|
||||
s->opc = dst;
|
||||
|
@ -1068,7 +1071,7 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
|
|||
|
||||
dst_addr = operand_address (*op, e);
|
||||
|
||||
s = new_statement (st_move, "<MOVEP>", deref);
|
||||
s = new_statement (st_ptrmove, "<MOVEP>", deref);
|
||||
s->opa = src_addr;
|
||||
//FIXME large types
|
||||
s->opb = short_operand (type_size (type), e);
|
||||
|
|
Loading…
Reference in a new issue