Encode function parameter alignment

The encoding is 3:5 giving 3 bits for alignment (log2) and 5 bits for
size, with alignment in the 3 most significant bits. This keeps the
format backwards compatible as until doubles were added, all types were
aligned to 1 word which gets encoded as 0, and the size is unaffected.
This commit is contained in:
Bill Currie 2020-02-16 17:10:43 +09:00
parent 1bc08c59f6
commit 7a399c956b
7 changed files with 91 additions and 7 deletions

View file

@ -423,6 +423,11 @@ typedef struct ddef_s {
pr_int_t s_name;
} ddef_t;
typedef struct dparmsize_s {
uint8_t size:5;
uint8_t alignment:3;
} dparmsize_t;
#define DEF_SAVEGLOBAL (1<<15)
#define MAX_PARMS 8
@ -438,7 +443,7 @@ typedef struct dfunction_s {
pr_int_t s_file; // source file defined in
pr_int_t numparms;
uint8_t parm_size[MAX_PARMS];
dparmsize_t parm_size[MAX_PARMS];
} dfunction_t;
typedef union pr_type_u {

View file

@ -497,6 +497,8 @@ qfo_t *qfo_new (void);
*/
void qfo_delete (qfo_t *qfo);
__attribute__((const)) int qfo_log2 (unsigned x);
///@}
#endif//__obj_file_h

View file

@ -53,7 +53,7 @@ qfcc_DEPENDENCIES= $(QFCC_DEPS)
qfprogs_SOURCES= \
disassemble.c dump_globals.c dump_lines.c dump_modules.c dump_strings.c \
obj_file.c qfprogs.c strpool.c stub.c
obj_file.c qfprogs.c strpool.c stub.c type.c
qfprogs_LDADD= $(QFCC_LIBS)
qfprogs_DEPENDENCIES= $(QFCC_DEPS)

View file

@ -217,7 +217,8 @@ dump_functions (progs_t *pr)
else
count = func->numparms;
for (j = 0; j < count; j++)
printf (" %d", func->parm_size[j]);
printf (" %d:%d", func->parm_size[j].alignment,
func->parm_size[j].size);
printf (") %d @ %x", func->locals, func->parm_start);
puts ("");
if (pr->debug) {

View file

@ -665,7 +665,7 @@ get_def_type (qfo_t *qfo, pointer_t type)
return ev_invalid;
}
static __attribute__((pure)) etype_t
static __attribute__((pure)) int
get_type_size (qfo_t *qfo, pointer_t type)
{
qfot_type_t *type_def;
@ -701,6 +701,62 @@ get_type_size (qfo_t *qfo, pointer_t type)
return 0;
}
int
qfo_log2 (unsigned x)
{
int log2 = 0;
while (x > 1) {
x >>= 1;
log2++;
}
return log2;
}
static __attribute__((pure)) int
get_type_alignment_log (qfo_t *qfo, pointer_t type)
{
qfot_type_t *type_def;
int i, alignment;
if (type >= qfo->spaces[qfo_type_space].data_size)
return 0;
type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type);
switch ((ty_meta_e)type_def->meta) {
case ty_none:
// field, pointer and function types store their basic type in
// the same location.
return qfo_log2 (ev_types[type_def->t.type]->alignment);
case ty_struct:
case ty_union:
for (i = alignment = 0; i < type_def->t.strct.num_fields; i++) {
qfot_var_t *field = type_def->t.strct.fields + i;
int a;
a = get_type_alignment_log (qfo, field->type);
if (a > alignment) {
alignment = a;
}
}
return alignment;
case ty_enum:
return qfo_log2 (ev_types[ev_integer]->alignment);
case ty_array:
return get_type_alignment_log (qfo, type_def->t.array.type);
case ty_class:
return 0; // FIXME
}
return 0;
}
static __attribute__((pure)) dparmsize_t
get_parmsize (qfo_t *qfo, pointer_t type)
{
dparmsize_t parmsize = {
get_type_size (qfo, type),
get_type_alignment_log (qfo, type),
};
return parmsize;
}
static void
function_params (qfo_t *qfo, qfo_func_t *func, dfunction_t *df)
{
@ -716,8 +772,9 @@ function_params (qfo_t *qfo, qfo_func_t *func, dfunction_t *df)
df->numparms = num_params = type->t.func.num_params;
if (num_params < 0)
num_params = ~num_params;
for (i = 0; i < num_params; i++)
df->parm_size[i] = get_type_size (qfo, type->t.func.param_types[i]);
for (i = 0; i < num_params; i++) {
df->parm_size[i] = get_parmsize (qfo, type->t.func.param_types[i]);
}
}
static void

View file

@ -418,8 +418,11 @@ finish_link (void)
flags = (QFOD_GLOBAL | QFOD_CONSTANT | QFOD_INITIALIZED | QFOD_NOSAVE);
if (options.code.progsversion != PROG_ID_VERSION) {
pr_int_t param_size = type_size (&type_param);
pr_int_t param_alignment = qfo_log2 (type_param.alignment);
linker_add_def (".param_size", &type_integer, flags,
&param_size);
linker_add_def (".param_alignment", &type_integer, flags,
&param_alignment);
}
if (options.code.debug) {

View file

@ -2,6 +2,8 @@
# include "config.h"
#endif
#include <stdlib.h>
#include "class.h"
#include "codespace.h"
#include "diagnostic.h"
@ -12,9 +14,12 @@
#include "expr.h"
#include "function.h"
#include "obj_file.h"
#include "obj_type.h"
#include "options.h"
#include "qfcc.h"
#include "strpool.h"
#include "struct.h"
#include "symtab.h"
#include "type.h"
#include "value.h"
@ -23,11 +28,22 @@ options_t options;
int num_linenos;
pr_lineno_t *linenos;
pr_info_t pr;
type_t type_Class;
type_t type_SEL;
type_t type_id;
__attribute__((const)) string_t ReuseString (const char *str) {return 0;}
void encode_type (struct dstring_s *str, const type_t *type) {}
__attribute__((const)) codespace_t *codespace_new (void) {return 0;}
void codespace_addcode (codespace_t *codespace, struct dstatement_s *code, int size) {}
__attribute__((const)) int function_parms (function_t *f, byte *parm_size) {return 0;}
void def_to_ddef (def_t *def, ddef_t *ddef, int aux) {}
__attribute__((noreturn)) void _internal_error (expr_t *e, const char *file, int line, const char *fmt, ...) {abort();}
__attribute__((const)) expr_t *_warning (expr_t *e, const char *file, int line, const char *fmt, ...) {return 0;}
__attribute__((const)) expr_t *_error (expr_t *e, const char *file, int line, const char *fmt, ...) {return 0;}
__attribute__((const)) symbol_t *make_structure (const char *name, int su, struct_def_t *defs, type_t *type) {return 0;}
__attribute__((const)) symbol_t *symtab_addsymbol (symtab_t *symtab, symbol_t *symbol) {return 0;}
__attribute__((const)) symbol_t *new_symbol_type (const char *name, type_t *type) {return 0;}
__attribute__((const)) def_t *qfo_encode_type (type_t *type) {return 0;}
__attribute__((const)) int obj_types_assignable (const type_t *dst, const type_t *src) {return 0;}
void print_protocollist (struct dstring_s *dstr, protocollist_t *protocollist) {}
int obj_is_id (const type_t *type){return type->type;}
int compare_protocols (protocollist_t *protos1, protocollist_t *protos2){return protos1->count - protos2->count;}