[qfcc] Use locals and params_start to describe stack frame

This is necessary to get statement disassembly working, and likely
debugging in general. locals is the total size of the stack frame and
thus reaches above the function-entry stack pointer, and params_start is
the local space relative start of the parameters. Thus, knowing the
function-entry stack pointer, the bottom of the locals space can be
found by subtracting params_start, and the top of the locals space by
adding (locals - params_start).
This commit is contained in:
Bill Currie 2022-01-27 11:25:50 +09:00
parent 42db8514ae
commit 0123e12304
4 changed files with 18 additions and 5 deletions

View file

@ -65,7 +65,7 @@ typedef struct function_s {
int code; ///< first statement
int function_num;
int line_info;
int local_defs;
int params_start;///< relative to locals space. 0 for v6p
pr_string_t s_file; ///< source file with definition
pr_string_t s_name; ///< name of function in output
const struct type_s *type; ///< function's type without aliases

View file

@ -211,7 +211,9 @@ typedef struct qfo_func_s {
pr_uint_t relocs; ///< Index to first ::qfo_reloc_t reloc record.
pr_uint_t num_relocs; ///< Number of reloc records.
//@}
pr_int_t reserved[2];
pr_uint_t params_start; ///< locals_space relative start of parameters
///< always 0 for v6/v6p progs
pr_int_t reserved;
} qfo_func_t;
/** Evil source of many headaches. The whole reason I've started writing this

View file

@ -773,6 +773,8 @@ build_code_function (symbol_t *fsym, expr_t *state_expr, expr_t *statements)
// first
defspace_t *space = defspace_new (ds_virtual);
func->params_start = 0;
merge_spaces (space, func->parameters->space, 1);
func->parameters->space = space;
@ -790,15 +792,19 @@ build_code_function (symbol_t *fsym, expr_t *state_expr, expr_t *statements)
merge_spaces (space, func->locals->space, 4);
func->locals->space = space;
// allocate 0 words to force alignment
defspace_alloc_aligned_highwater (space, 0, 4);
// allocate 0 words to force alignment and get the address
func->params_start = defspace_alloc_aligned_highwater (space, 0, 4);
dstatement_t *st = &pr.code->code[func->code];
if (st->op == OP_ADJSTK) {
st->b = -space->size;
st->b = -func->params_start;
}
merge_spaces (space, func->parameters->space, 4);
func->parameters->space = space;
// force the alignment again so the full stack slot is counted when
// the final parameter is smaller than 4 words
defspace_alloc_aligned_highwater (space, 0, 4);
}
return fsym->s.func;
}

View file

@ -314,6 +314,7 @@ qfo_encode_functions (qfo_t *qfo, qfo_def_t **defs, qfo_reloc_t **relocs,
q->line_info = f->line_info;
q->relocs = *relocs - qfo->relocs;
q->num_relocs = qfo_encode_relocs (f->refs, relocs, q - qfo->funcs);
q->params_start = f->params_start;
}
}
@ -530,6 +531,7 @@ qfo_write (qfo_t *qfo, const char *filename)
funcs[i].line_info = LittleLong (qfo->funcs[i].line_info);
funcs[i].relocs = LittleLong (qfo->funcs[i].relocs);
funcs[i].num_relocs = LittleLong (qfo->funcs[i].num_relocs);
funcs[i].params_start = LittleLong (qfo->funcs[i].params_start);
}
for (i = 0; i < qfo->num_lines; i++) {
lines[i].fa.addr = LittleLong (qfo->lines[i].fa.addr);
@ -1148,6 +1150,9 @@ qfo_to_progs (qfo_t *in_qfo, int *size)
space->defs[j].offset += globals_info.locals_start;
if (!options.code.local_merging)
globals_info.locals_start += align_globals_size (df->locals);
} else {
// relative to start of locals for Ruamoko progs
df->params_start = qf->params_start;
}
df->profile = 0;
df->name = qf->name;