2011-01-19 06:47:45 +00:00
|
|
|
/*
|
|
|
|
statement.h
|
|
|
|
|
|
|
|
Internal statements
|
|
|
|
|
|
|
|
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
|
|
|
|
|
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
|
|
Date: 2011/01/18
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
#ifndef statement_h
|
|
|
|
#define statement_h
|
|
|
|
|
2022-01-08 15:26:52 +00:00
|
|
|
#include "QF/progs/pr_comp.h"
|
2012-05-08 02:43:29 +00:00
|
|
|
|
2011-01-19 06:47:45 +00:00
|
|
|
typedef enum {
|
2012-12-05 10:47:22 +00:00
|
|
|
op_def,
|
2011-01-19 06:47:45 +00:00
|
|
|
op_value,
|
|
|
|
op_label,
|
|
|
|
op_temp,
|
2012-12-11 06:52:37 +00:00
|
|
|
op_alias,
|
2020-03-14 08:47:23 +00:00
|
|
|
op_nil,
|
2021-12-25 03:42:15 +00:00
|
|
|
op_pseudo,
|
2011-01-19 06:47:45 +00:00
|
|
|
} op_type_e;
|
|
|
|
|
2021-12-25 03:42:15 +00:00
|
|
|
struct expr_s;
|
|
|
|
|
2020-03-16 03:15:55 +00:00
|
|
|
typedef struct tempop_s {
|
2012-07-16 08:37:13 +00:00
|
|
|
struct def_s *def;
|
2019-06-10 14:48:58 +00:00
|
|
|
int offset;
|
2012-12-01 02:10:47 +00:00
|
|
|
struct type_s *type;
|
2012-11-05 10:00:57 +00:00
|
|
|
struct flowvar_s *flowvar;
|
2012-07-16 08:37:13 +00:00
|
|
|
struct daglabel_s *daglabel;
|
2012-12-05 10:47:22 +00:00
|
|
|
struct operand_s *alias;
|
2012-12-06 00:40:16 +00:00
|
|
|
struct operand_s *alias_ops;
|
2012-11-18 10:08:16 +00:00
|
|
|
int users;
|
2019-06-11 15:37:02 +00:00
|
|
|
int flowaddr; ///< "address" of temp in flow analysis, != 0
|
2012-07-16 08:37:13 +00:00
|
|
|
} tempop_t;
|
|
|
|
|
2021-12-25 03:42:15 +00:00
|
|
|
typedef struct pseudoop_s {
|
|
|
|
struct pseudoop_s *next;
|
|
|
|
const char *name;
|
|
|
|
struct flowvar_s *flowvar;
|
|
|
|
void (*uninitialized) (struct expr_s *expr, struct pseudoop_s *op);
|
|
|
|
} pseudoop_t;
|
|
|
|
|
2011-01-19 06:47:45 +00:00
|
|
|
typedef struct operand_s {
|
|
|
|
struct operand_s *next;
|
2011-01-21 01:54:40 +00:00
|
|
|
op_type_e op_type;
|
2020-03-14 08:47:23 +00:00
|
|
|
struct type_s *type; ///< possibly override def's/nil's type
|
2011-03-23 12:32:14 +00:00
|
|
|
int size; ///< for structures
|
2020-03-11 03:51:34 +00:00
|
|
|
struct expr_s *expr; ///< expression generating this operand
|
2020-03-14 08:44:08 +00:00
|
|
|
void *return_addr; ///< who created this operand
|
2011-01-19 06:47:45 +00:00
|
|
|
union {
|
2012-12-05 10:47:22 +00:00
|
|
|
struct def_s *def;
|
2011-01-19 06:47:45 +00:00
|
|
|
struct ex_value_s *value;
|
|
|
|
struct ex_label_s *label;
|
2012-07-16 08:37:13 +00:00
|
|
|
tempop_t tempop;
|
2012-12-11 06:52:37 +00:00
|
|
|
struct operand_s *alias;
|
2021-12-25 03:42:15 +00:00
|
|
|
pseudoop_t *pseudoop;
|
2021-12-25 03:40:24 +00:00
|
|
|
};
|
2011-01-19 06:47:45 +00:00
|
|
|
} operand_t;
|
|
|
|
|
2012-11-16 07:16:06 +00:00
|
|
|
/** Overall type of statement.
|
|
|
|
|
|
|
|
Statement types are broken down into expressions (binary and unary,
|
|
|
|
includes address and pointer dereferencing (read)), assignment, pointer
|
2020-03-17 12:39:49 +00:00
|
|
|
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)).
|
2012-11-16 07:16:06 +00:00
|
|
|
*/
|
|
|
|
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;
|
2020-03-17 12:39:49 +00:00
|
|
|
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
|
2012-11-16 07:16:06 +00:00
|
|
|
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
|
|
|
|
} st_type_t;
|
|
|
|
|
2011-01-19 06:47:45 +00:00
|
|
|
typedef struct statement_s {
|
|
|
|
struct statement_s *next;
|
2012-11-16 07:16:06 +00:00
|
|
|
st_type_t type;
|
2011-01-19 06:47:45 +00:00
|
|
|
const char *opcode;
|
|
|
|
operand_t *opa;
|
|
|
|
operand_t *opb;
|
|
|
|
operand_t *opc;
|
2012-11-05 06:21:40 +00:00
|
|
|
struct expr_s *expr; ///< source expression for this statement
|
|
|
|
int number; ///< number of this statement in function
|
2021-12-25 03:42:15 +00:00
|
|
|
operand_t *use; ///< list of pseudo operands used
|
|
|
|
operand_t *def; ///< list of pseudo operands defined
|
|
|
|
operand_t *kill; ///< list of pseudo operands killed
|
2011-01-19 06:47:45 +00:00
|
|
|
} statement_t;
|
|
|
|
|
|
|
|
typedef struct sblock_s {
|
|
|
|
struct sblock_s *next;
|
2011-01-25 06:45:31 +00:00
|
|
|
struct reloc_s *relocs;
|
2011-01-28 02:41:53 +00:00
|
|
|
struct ex_label_s *labels;
|
2012-12-19 07:08:10 +00:00
|
|
|
struct flownode_s *flownode;///< flow node for this block
|
2011-01-25 06:45:31 +00:00
|
|
|
int offset; ///< offset of first statement of block
|
2011-01-28 02:41:53 +00:00
|
|
|
int reachable;
|
2012-10-30 08:41:40 +00:00
|
|
|
int number; ///< number of this block in flow graph
|
2011-01-19 06:47:45 +00:00
|
|
|
statement_t *statements;
|
|
|
|
statement_t **tail;
|
|
|
|
} sblock_t;
|
|
|
|
|
|
|
|
struct expr_s;
|
2012-11-07 05:09:01 +00:00
|
|
|
struct type_s;
|
2012-12-11 02:31:55 +00:00
|
|
|
struct dstring_s;
|
2011-01-19 06:47:45 +00:00
|
|
|
|
2020-03-17 13:46:23 +00:00
|
|
|
extern const char *op_type_names[];
|
|
|
|
extern const char *st_type_names[];
|
|
|
|
|
2018-10-09 03:35:01 +00:00
|
|
|
const char *optype_str (op_type_e type) __attribute__((const));
|
2012-12-05 10:47:22 +00:00
|
|
|
|
2020-03-14 08:47:23 +00:00
|
|
|
operand_t *nil_operand (struct type_s *type, struct expr_s *expr);
|
2020-03-11 03:51:34 +00:00
|
|
|
operand_t *def_operand (struct def_s *def, struct type_s *type,
|
|
|
|
struct expr_s *expr);
|
|
|
|
operand_t *return_operand (struct type_s *type, struct expr_s *expr);
|
|
|
|
operand_t *value_operand (struct ex_value_s *value, struct expr_s *expr);
|
2019-06-27 12:37:48 +00:00
|
|
|
int tempop_overlap (tempop_t *t1, tempop_t *t2) __attribute__((pure));
|
2020-03-11 03:51:34 +00:00
|
|
|
operand_t *temp_operand (struct type_s *type, struct expr_s *expr);
|
2019-06-16 07:52:49 +00:00
|
|
|
int tempop_visit_all (tempop_t *tempop, int overlap,
|
|
|
|
int (*visit) (tempop_t *, void *), void *data);
|
2020-03-11 03:51:34 +00:00
|
|
|
operand_t *alias_operand (struct type_s *type, operand_t *op,
|
|
|
|
struct expr_s *expr);
|
2020-03-14 08:44:08 +00:00
|
|
|
operand_t *label_operand (struct expr_s *label);
|
2012-12-13 03:49:00 +00:00
|
|
|
void free_operand (operand_t *op);
|
|
|
|
|
2012-11-07 05:09:01 +00:00
|
|
|
sblock_t *new_sblock (void);
|
2012-11-16 07:16:06 +00:00
|
|
|
statement_t *new_statement (st_type_t type, const char *opcode,
|
|
|
|
struct expr_s *expr);
|
2018-10-09 03:35:01 +00:00
|
|
|
int statement_is_cond (statement_t *s) __attribute__((pure));
|
|
|
|
int statement_is_goto (statement_t *s) __attribute__((pure));
|
|
|
|
int statement_is_jumpb (statement_t *s) __attribute__((pure));
|
|
|
|
int statement_is_call (statement_t *s) __attribute__((pure));
|
|
|
|
int statement_is_return (statement_t *s) __attribute__((pure));
|
|
|
|
sblock_t *statement_get_target (statement_t *s) __attribute__((pure));
|
2012-11-30 05:06:52 +00:00
|
|
|
sblock_t **statement_get_targetlist (statement_t *s);
|
2012-11-07 05:09:01 +00:00
|
|
|
void sblock_add_statement (sblock_t *sblock, statement_t *statement);
|
2011-01-19 06:47:45 +00:00
|
|
|
sblock_t *make_statements (struct expr_s *expr);
|
2012-12-01 02:13:45 +00:00
|
|
|
void statements_count_temps (sblock_t *sblock);
|
|
|
|
|
2018-08-23 11:05:16 +00:00
|
|
|
void print_operand (operand_t *op);
|
2011-01-19 06:47:45 +00:00
|
|
|
void print_statement (statement_t *s);
|
2012-11-07 05:07:21 +00:00
|
|
|
void dump_dot_sblock (void *data, const char *fname);
|
2012-12-11 02:31:55 +00:00
|
|
|
void dot_sblock (struct dstring_s *dstr, sblock_t *sblock, int blockno);
|
2012-11-01 03:19:38 +00:00
|
|
|
void print_sblock (sblock_t *sblock, const char *filename);
|
2012-05-08 02:43:29 +00:00
|
|
|
const char *operand_string (operand_t *op);
|
2011-01-19 06:47:45 +00:00
|
|
|
|
|
|
|
#endif//statement_h
|