mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
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:
parent
1bc08c59f6
commit
7a399c956b
7 changed files with 91 additions and 7 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
¶m_size);
|
||||
linker_add_def (".param_alignment", &type_integer, flags,
|
||||
¶m_alignment);
|
||||
}
|
||||
|
||||
if (options.code.debug) {
|
||||
|
|
|
@ -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;}
|
||||
|
|
Loading…
Reference in a new issue