[qfcc] Ensure adjstk and with always come first

While I think the reason the dags code moved an instruction before
adjstk and with was they shared a constant with that instruction (which
is a different bug), this ensures other instructions cannot get
reordered in front of adjstk and with, as doing so would cause any such
instructions to access incorrect data.
This commit is contained in:
Bill Currie 2022-01-26 12:56:15 +09:00
parent 0b9b6955aa
commit 90b40e7e52
1 changed files with 20 additions and 5 deletions

View File

@ -729,17 +729,32 @@ build_code_function (symbol_t *fsym, expr_t *state_expr, expr_t *statements)
} }
function_t *func = fsym->s.func; function_t *func = fsym->s.func;
if (options.code.progsversion == PROG_VERSION) { if (options.code.progsversion == PROG_VERSION) {
/* Create a function entry block to set up the stack frame and add the
* actual function code to that block. This ensure that the adjstk and
* with statements always come first, regardless of what ideas the
* optimizer gets.
*/
expr_t *e; expr_t *e;
e = new_with_expr (2, LOCALS_REG, new_short_expr (0)); expr_t *entry = new_block_expr ();
e->file = func->def->file; entry->file = func->def->file;
e->line = func->def->line; entry->line = func->def->line;
prepend_expr (statements, e);
e = new_adjstk_expr (0, 0); e = new_adjstk_expr (0, 0);
e->file = func->def->file; e->file = func->def->file;
e->line = func->def->line; e->line = func->def->line;
prepend_expr (statements, e); append_expr (entry, e);
e = new_with_expr (2, LOCALS_REG, new_short_expr (0));
e->file = func->def->file;
e->line = func->def->line;
append_expr (entry, e);
append_expr (entry, statements);
statements = entry;
/* Mark all local defs as using the base register used for stack
* references.
*/
func->temp_reg = LOCALS_REG; func->temp_reg = LOCALS_REG;
for (def_t *def = func->locals->space->defs; def; def = def->next) { for (def_t *def = func->locals->space->defs; def; def = def->next) {
if (def->local || def->param) { if (def->local || def->param) {