mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 14:21:36 +00:00
ast_call_codegen, ir_block_create_call plus call-related functions, ir_value->outtype TODO: fill outtype in ir_value
This commit is contained in:
parent
7363e88cd7
commit
01b3f5ef58
3 changed files with 106 additions and 0 deletions
47
ast.c
47
ast.c
|
@ -1177,5 +1177,52 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out)
|
||||
{
|
||||
/* TODO: call ir codegen */
|
||||
ast_expression_codegen *cgen;
|
||||
ir_value_vector params;
|
||||
ir_instr *callinstr;
|
||||
size_t i;
|
||||
|
||||
ir_value *funval = NULL;
|
||||
|
||||
/* return values are never rvalues */
|
||||
(void)lvalue;
|
||||
|
||||
cgen = self->func->expression.codegen;
|
||||
if (!(*cgen)((ast_expression*)(self->func), func, false, &funval))
|
||||
return false;
|
||||
if (!funval)
|
||||
return false;
|
||||
|
||||
MEM_VECTOR_INIT(¶ms, v);
|
||||
|
||||
/* parameters */
|
||||
for (i = 0; i < self->params_count; ++i)
|
||||
{
|
||||
ir_value *param;
|
||||
ast_expression *expr = self->params[i];
|
||||
|
||||
cgen = expr->expression.codegen;
|
||||
if (!(*cgen)(expr, func, false, ¶m))
|
||||
goto error;
|
||||
if (!param)
|
||||
goto error;
|
||||
if (!ir_value_vector_v_add(¶ms, param))
|
||||
goto error;
|
||||
}
|
||||
|
||||
callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval, funval->outtype);
|
||||
if (!callinstr)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < params.v_count; ++i) {
|
||||
if (!ir_call_param(callinstr, params.v[i]))
|
||||
goto error;
|
||||
}
|
||||
|
||||
*out = ir_call_value(callinstr);
|
||||
|
||||
return true;
|
||||
error:
|
||||
MEM_VECTOR_CLEAR(¶ms, v);
|
||||
return false;
|
||||
}
|
||||
|
|
45
ir.c
45
ir.c
|
@ -44,6 +44,8 @@ size_t type_sizeof[TYPE_COUNT] = {
|
|||
3, /* TYPE_VARIANT */
|
||||
};
|
||||
|
||||
MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
|
||||
|
||||
/***********************************************************************
|
||||
*IR Builder
|
||||
*/
|
||||
|
@ -362,6 +364,7 @@ ir_instr* ir_instr_new(ir_block* owner, int op)
|
|||
return self;
|
||||
}
|
||||
MEM_VEC_FUNCTIONS(ir_instr, ir_phi_entry_t, phi)
|
||||
MEM_VEC_FUNCTIONS(ir_instr, ir_value*, params)
|
||||
|
||||
void ir_instr_delete(ir_instr *self)
|
||||
{
|
||||
|
@ -432,6 +435,7 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
|
|||
self = (ir_value*)mem_a(sizeof(*self));
|
||||
self->vtype = vtype;
|
||||
self->fieldtype = TYPE_VOID;
|
||||
self->outtype = TYPE_VOID;
|
||||
self->store = storetype;
|
||||
MEM_VECTOR_INIT(self, reads);
|
||||
MEM_VECTOR_INIT(self, writes);
|
||||
|
@ -1026,6 +1030,47 @@ bool ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
|
|||
return ir_instr_phi_add(self, pe);
|
||||
}
|
||||
|
||||
/* call related code */
|
||||
ir_instr* ir_block_create_call(ir_block *self, const char *label, ir_value *func, int ot)
|
||||
{
|
||||
ir_value *out;
|
||||
ir_instr *in;
|
||||
in = ir_instr_new(self, INSTR_CALL0);
|
||||
if (!in)
|
||||
return NULL;
|
||||
out = ir_value_out(self->owner, label, store_value, ot);
|
||||
if (!out) {
|
||||
ir_instr_delete(in);
|
||||
return NULL;
|
||||
}
|
||||
if (!ir_instr_op(in, 0, out, true) ||
|
||||
!ir_instr_op(in, 1, func, false) ||
|
||||
!ir_block_instr_add(self, in))
|
||||
{
|
||||
ir_instr_delete(in);
|
||||
ir_value_delete(out);
|
||||
return NULL;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
ir_value* ir_call_value(ir_instr *self)
|
||||
{
|
||||
return self->_ops[0];
|
||||
}
|
||||
|
||||
bool ir_call_param(ir_instr* self, ir_value *v)
|
||||
{
|
||||
if (!ir_instr_params_add(self, v))
|
||||
return false;
|
||||
if (!ir_value_reads_add(v, self)) {
|
||||
if (!ir_instr_params_remove(self, self->params_count-1))
|
||||
GMQCC_SUPRESS_EMPTY_BODY;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* binary op related code */
|
||||
|
||||
ir_value* ir_block_create_binop(ir_block *self,
|
||||
|
|
14
ir.h
14
ir.h
|
@ -40,6 +40,8 @@ typedef struct ir_value_s {
|
|||
lex_ctx context;
|
||||
/* even the IR knows the subtype of a field */
|
||||
int fieldtype;
|
||||
/* and the output type of a function */
|
||||
int outtype;
|
||||
|
||||
MEM_VECTOR_MAKE(struct ir_instr_s*, reads);
|
||||
MEM_VECTOR_MAKE(struct ir_instr_s*, writes);
|
||||
|
@ -100,6 +102,13 @@ bool ir_values_overlap(const ir_value*, const ir_value*);
|
|||
void ir_value_dump(ir_value*, int (*oprintf)(const char*,...));
|
||||
void ir_value_dump_life(ir_value *self, int (*oprintf)(const char*,...));
|
||||
|
||||
/* A vector of IR values */
|
||||
typedef struct {
|
||||
MEM_VECTOR_MAKE(ir_value*, v);
|
||||
} ir_value_vector;
|
||||
MEM_VECTOR_PROTO(ir_value_vector, ir_value*, v);
|
||||
|
||||
/* PHI data */
|
||||
typedef struct ir_phi_entry_s
|
||||
{
|
||||
ir_value *value;
|
||||
|
@ -129,6 +138,8 @@ void ir_instr_delete(ir_instr*);
|
|||
MEM_VECTOR_PROTO(ir_value, ir_phi_entry_t, phi);
|
||||
bool GMQCC_WARN ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
|
||||
|
||||
MEM_VECTOR_PROTO(ir_value, ir_value*, params);
|
||||
|
||||
void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
|
||||
|
||||
/* block */
|
||||
|
@ -187,6 +198,9 @@ ir_value* ir_block_create_div(ir_block*, const char *label, ir_value *l, ir_valu
|
|||
ir_instr* ir_block_create_phi(ir_block*, const char *label, int vtype);
|
||||
ir_value* ir_phi_value(ir_instr*);
|
||||
bool GMQCC_WARN ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
|
||||
ir_instr* ir_block_create_call(ir_block*, const char *label, ir_value *func, int otype);
|
||||
ir_value* ir_call_value(ir_instr*);
|
||||
bool GMQCC_WARN ir_call_param(ir_instr*, ir_value*);
|
||||
|
||||
bool GMQCC_WARN ir_block_create_return(ir_block*, ir_value *opt_value);
|
||||
|
||||
|
|
Loading…
Reference in a new issue