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,
|
Statement types are broken down into expressions (binary and unary,
|
||||||
includes address and pointer dereferencing (read)), assignment, pointer
|
includes address and pointer dereferencing (read)), assignment, pointer
|
||||||
assignment (write to dereference pointer), move (special case of pointer
|
assignment (write to dereference pointer), move (special case of
|
||||||
assignment), state, function related (call, rcall, return and done), and
|
assignment), pointer move (special case of pointer assignment), state,
|
||||||
flow control (conditional branches, goto, jump (single pointer and jump
|
function related (call, rcall, return and done), and flow control
|
||||||
table)).
|
(conditional branches, goto, jump (single pointer and jump table)).
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
st_none, ///< not a (valid) statement. Used in dags.
|
st_none, ///< not a (valid) statement. Used in dags.
|
||||||
st_expr, ///< c = a op b; or c = op a;
|
st_expr, ///< c = a op b; or c = op a;
|
||||||
st_assign, ///< b = a
|
st_assign, ///< b = a
|
||||||
st_ptrassign, ///< *b = a; or *(b + c) = 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_state, ///< state (a, b); or state (a, b, c)
|
||||||
st_func, ///< call, rcall or return/done
|
st_func, ///< call, rcall or return/done
|
||||||
st_flow, ///< if/ifa/ifae/ifb/ifbe/ifnot or goto or jump/jumpb
|
st_flow, ///< if/ifa/ifae/ifb/ifbe/ifnot or goto or jump/jumpb
|
||||||
|
|
|
@ -49,8 +49,10 @@
|
||||||
|
|
||||||
#include "dags.h"
|
#include "dags.h"
|
||||||
#include "diagnostic.h"
|
#include "diagnostic.h"
|
||||||
|
#include "dot.h"
|
||||||
#include "flow.h"
|
#include "flow.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
#include "options.h"
|
||||||
#include "qfcc.h"
|
#include "qfcc.h"
|
||||||
#include "statements.h"
|
#include "statements.h"
|
||||||
#include "strpool.h"
|
#include "strpool.h"
|
||||||
|
@ -133,6 +135,11 @@ daglabel_string (daglabel_t *label)
|
||||||
// operand_string might use quote_string, which returns a pointer to
|
// operand_string might use quote_string, which returns a pointer to
|
||||||
// a static variable.
|
// a static variable.
|
||||||
dstring_copystr (str, operand_string (label->op));
|
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);
|
return quote_string (str->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,10 +737,13 @@ dag_create (flownode_t *flownode)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dag_make_children (dag, s, operands, children);
|
dag_make_children (dag, s, operands, children);
|
||||||
if (s->type == st_flow || s->type == st_func)
|
if (s->type == st_flow || s->type == st_func) {
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
if (children[i])
|
if (children[i]) {
|
||||||
dag_make_var_live (live_vars, operands[i + 1]);
|
dag_make_var_live (live_vars, operands[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
op = opcode_label (dag, s->opcode, s->expr);
|
op = opcode_label (dag, s->opcode, s->expr);
|
||||||
n = children[0];
|
n = children[0];
|
||||||
if (s->type != st_assign
|
if (s->type != st_assign
|
||||||
|
@ -759,7 +769,12 @@ dag_create (flownode_t *flownode)
|
||||||
labels = malloc (dag->num_labels * sizeof (daglabel_t *));
|
labels = malloc (dag->num_labels * sizeof (daglabel_t *));
|
||||||
memcpy (labels, dag->labels, dag->num_labels * sizeof (daglabel_t *));
|
memcpy (labels, dag->labels, dag->num_labels * sizeof (daglabel_t *));
|
||||||
dag->labels = labels;
|
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_remove_dead_vars (dag, live_vars);
|
||||||
dag_sort_nodes (dag);
|
dag_sort_nodes (dag);
|
||||||
set_delete (live_vars);
|
set_delete (live_vars);
|
||||||
|
@ -972,6 +987,9 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
||||||
dst = operands[0];
|
dst = operands[0];
|
||||||
break;
|
break;
|
||||||
case st_move:
|
case st_move:
|
||||||
|
case st_ptrmove:
|
||||||
|
case st_memset:
|
||||||
|
case st_ptrmemset:
|
||||||
if (!strcmp (dagnode->label->opcode, "<MOVE>")) {
|
if (!strcmp (dagnode->label->opcode, "<MOVE>")) {
|
||||||
dst = generate_moves (dag, block, dagnode);
|
dst = generate_moves (dag, block, dagnode);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1116,6 +1116,9 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
break;
|
break;
|
||||||
case st_ptrassign:
|
case st_ptrassign:
|
||||||
case st_move:
|
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->opa, 1);
|
||||||
flow_add_op_var (use, s->opb, 1);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
if (!strcmp (s->opcode, "<MOVE>")
|
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_set = opcode_sets[0];
|
||||||
const char *opcode;
|
const char *opcode;
|
||||||
int need_ptr = 0;
|
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) {
|
if ((src && src->op_type == op_nil) || src_expr->type == ex_nil) {
|
||||||
// switch to memset because nil is type agnostic 0 and structures
|
// 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) {
|
if (op) {
|
||||||
*op = nil_operand (dst_type, src_expr);
|
*op = nil_operand (dst_type, src_expr);
|
||||||
}
|
}
|
||||||
|
type = st_memset;
|
||||||
if (is_indirect (dst_expr)) {
|
if (is_indirect (dst_expr)) {
|
||||||
goto dereference_dst;
|
goto dereference_dst;
|
||||||
}
|
}
|
||||||
|
@ -815,9 +816,10 @@ dereference_dst:
|
||||||
opcode = opcode_set[0];
|
opcode = opcode_set[0];
|
||||||
} else {
|
} else {
|
||||||
opcode = opcode_set[1];
|
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->opa = src;
|
||||||
s->opb = size;
|
s->opb = size;
|
||||||
s->opc = dst;
|
s->opc = dst;
|
||||||
|
@ -932,7 +934,8 @@ expr_move (sblock_t *sblock, expr_t *e, operand_t **op)
|
||||||
dst = *op;
|
dst = *op;
|
||||||
sblock = statement_subexpr (sblock, src_expr, &src);
|
sblock = statement_subexpr (sblock, src_expr, &src);
|
||||||
sblock = statement_subexpr (sblock, size_expr, &size);
|
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->opa = src;
|
||||||
s->opb = size;
|
s->opb = size;
|
||||||
s->opc = dst;
|
s->opc = dst;
|
||||||
|
@ -1068,7 +1071,7 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
|
||||||
|
|
||||||
dst_addr = operand_address (*op, e);
|
dst_addr = operand_address (*op, e);
|
||||||
|
|
||||||
s = new_statement (st_move, "<MOVEP>", deref);
|
s = new_statement (st_ptrmove, "<MOVEP>", deref);
|
||||||
s->opa = src_addr;
|
s->opa = src_addr;
|
||||||
//FIXME large types
|
//FIXME large types
|
||||||
s->opb = short_operand (type_size (type), e);
|
s->opb = short_operand (type_size (type), e);
|
||||||
|
|
Loading…
Reference in a new issue