mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[qfcc] Get void return statements working
My little test program now builds with the Ruamoko ISA :) void cp (int *dst, int *src, int count) { while (count--) { *dst++ = *src++; } } Calls are broken (unimplemented), and non-void returns are not likely to work either (only partially implemented).
This commit is contained in:
parent
6487fe7ea7
commit
2b7a8387e7
3 changed files with 43 additions and 11 deletions
|
@ -452,7 +452,9 @@ dagnode_set_edges (dag_t *dag, dagnode_t *n)
|
|||
int first_param = 0;
|
||||
flowvar_t **flowvars = dag->flownode->graph->func->vars;
|
||||
|
||||
if (!strncmp (n->label->opcode, "rcall", 5)) {
|
||||
if (!strcmp (n->label->opcode, "call")) {
|
||||
internal_error (0, "not implemented");
|
||||
} else if (!strncmp (n->label->opcode, "rcall", 5)) {
|
||||
num_params = n->label->opcode + 6;
|
||||
first_param = 2;
|
||||
} else if (!strncmp (n->label->opcode, "call", 4)) {
|
||||
|
|
|
@ -1257,15 +1257,29 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
|||
}
|
||||
break;
|
||||
case st_func:
|
||||
if (strcmp (s->opcode, "return") == 0
|
||||
|| strcmp (s->opcode, "done") == 0) {
|
||||
flow_add_op_var (use, s->opa, 1);
|
||||
} else if (strcmp (s->opcode, "return_v") == 0) {
|
||||
if (statement_is_return (s)) {
|
||||
if (s->opc) {
|
||||
// ruamoko
|
||||
// opc always short
|
||||
short ret_mode = s->opc->value->v.short_val;
|
||||
// -1 is void
|
||||
// FIXME size and addressing
|
||||
if (ret_mode >= 0) {
|
||||
flow_add_op_var (use, s->opa, 1);
|
||||
}
|
||||
} else {
|
||||
// v6/v6p
|
||||
if (s->opa) {
|
||||
flow_add_op_var (use, s->opa, 1);
|
||||
}
|
||||
}
|
||||
if (use) {
|
||||
flow_add_op_var (use, &flow_params[0].op, 1);
|
||||
}
|
||||
}
|
||||
if (strncmp (s->opcode, "call", 4) == 0) {
|
||||
if (strcmp (s->opcode, "call") == 0) {
|
||||
internal_error (s->expr, "not implemented");
|
||||
} else if (strncmp (s->opcode, "call", 4) == 0) {
|
||||
start = 0;
|
||||
calln = s->opcode[5] - '0';
|
||||
flow_add_op_var (use, s->opa, 1);
|
||||
|
|
|
@ -1129,9 +1129,18 @@ statement_return (sblock_t *sblock, expr_t *e)
|
|||
}
|
||||
}
|
||||
s = new_statement (st_func, opcode, e);
|
||||
if (e->e.retrn.ret_val) {
|
||||
s->opa = return_operand (get_type (e->e.retrn.ret_val), e);
|
||||
sblock = statement_subexpr (sblock, e->e.retrn.ret_val, &s->opa);
|
||||
if (options.code.progsversion < PROG_VERSION) {
|
||||
if (e->e.retrn.ret_val) {
|
||||
s->opa = return_operand (get_type (e->e.retrn.ret_val), e);
|
||||
sblock = statement_subexpr (sblock, e->e.retrn.ret_val, &s->opa);
|
||||
}
|
||||
} else {
|
||||
if (e->e.retrn.ret_val) {
|
||||
} else {
|
||||
s->opa = short_operand (0, e);
|
||||
s->opb = short_operand (0, e);
|
||||
s->opc = short_operand (-1, e);
|
||||
}
|
||||
}
|
||||
sblock_add_statement (sblock, s);
|
||||
sblock->next = new_sblock ();
|
||||
|
@ -2134,8 +2143,15 @@ check_final_block (sblock_t *sblock)
|
|||
sblock = sblock->next;
|
||||
}
|
||||
s = new_statement (st_func, "return", 0);
|
||||
if (options.traditional || options.code.progsversion == PROG_ID_VERSION) {
|
||||
s->opa = return_operand (&type_void, 0);
|
||||
if (options.code.progsversion == PROG_VERSION) {
|
||||
s->opa = short_operand (0, 0);
|
||||
s->opb = short_operand (0, 0);
|
||||
s->opc = short_operand (-1, 0);
|
||||
} else {
|
||||
if (options.traditional
|
||||
|| options.code.progsversion == PROG_ID_VERSION) {
|
||||
s->opa = return_operand (&type_void, 0);
|
||||
}
|
||||
}
|
||||
sblock_add_statement (sblock, s);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue