From ba35ce71b3322c319f3d366d49cb58059e995ad2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 2 Oct 2023 23:33:37 +0900 Subject: [PATCH] [qfcc] Support 32-bit and 64-bit handle types 32-bit is nice because it's small, but 64-bit is handy for special handle encodings. --- include/QF/progs/pr_type.h | 2 ++ libs/gamecode/pr_debug.c | 4 +++ ruamoko/include/scene.h | 10 +++---- tools/qfcc/source/dump_globals.c | 2 ++ tools/qfcc/source/expr_binary.c | 50 ++++++++++++++++++++++++++++++-- tools/qfcc/source/obj_file.c | 6 ++++ tools/qfcc/source/qc-parse.y | 14 +++++++-- tools/qfcc/source/struct.c | 10 +++++-- tools/qfcc/source/type.c | 14 +++++++++ 9 files changed, 98 insertions(+), 14 deletions(-) diff --git a/include/QF/progs/pr_type.h b/include/QF/progs/pr_type.h index f20daf04c..b7555be50 100644 --- a/include/QF/progs/pr_type.h +++ b/include/QF/progs/pr_type.h @@ -50,6 +50,8 @@ typedef enum { ty_alias, ty_handle, ty_algebra, + + ty_meta_count } ty_meta_e; typedef struct qfot_alias_s { diff --git a/libs/gamecode/pr_debug.c b/libs/gamecode/pr_debug.c index 9f7344a75..49142df9e 100644 --- a/libs/gamecode/pr_debug.c +++ b/libs/gamecode/pr_debug.c @@ -262,6 +262,8 @@ pr_debug_type_size (const progs_t *pr, const qfot_type_t *type) return pr_debug_type_size (pr, aux_type); case ty_algebra: return 1; //FIXME wip + case ty_meta_count: + break; } return 0; } @@ -1094,6 +1096,8 @@ value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value) type = &G_STRUCT (data->pr, qfot_type_t, type->alias.aux_type); value_string (data, type, value); break; + case ty_meta_count: + break; } } diff --git a/ruamoko/include/scene.h b/ruamoko/include/scene.h index e2907ae6a..771070d39 100644 --- a/ruamoko/include/scene.h +++ b/ruamoko/include/scene.h @@ -14,11 +14,11 @@ typedef struct light_s { } light_t; //FIXME need a handle type -typedef struct { long handle; } scene_t; -typedef struct { long handle; } entity_t; -typedef struct { long handle; } transform_t; -typedef struct { long handle; } lightingdata_t; -typedef struct { int handle; } model_t; +typedef @handle(long) scene_h scene_t; +typedef @handle(long) entity_h entity_t; +typedef @handle(long) transform_h transform_t; +typedef @handle(long) lightingdata_h lightingdata_t; +typedef @handle(int) model_h model_t; scene_t Scene_NewScene (void); void Scene_DeleteScene (scene_t scene); diff --git a/tools/qfcc/source/dump_globals.c b/tools/qfcc/source/dump_globals.c index 32c72afc8..4746039d7 100644 --- a/tools/qfcc/source/dump_globals.c +++ b/tools/qfcc/source/dump_globals.c @@ -546,6 +546,8 @@ dump_qfo_types (qfo_t *qfo, int base_address) printf (" %s[%d] %5x %d\n", get_ev_type_name (type->type), type->algebra.width, type->algebra.algebra, type->algebra.element); + case ty_meta_count: + break; } } } diff --git a/tools/qfcc/source/expr_binary.c b/tools/qfcc/source/expr_binary.c index d091b9d11..6c9d106b3 100644 --- a/tools/qfcc/source/expr_binary.c +++ b/tools/qfcc/source/expr_binary.c @@ -829,6 +829,40 @@ static expr_type_t **binary_expr_types[ev_type_count] = { [ev_ulong] = ulong_x, }; +static expr_type_t int_handle[] = { + {EQ, &type_int}, + {NE, &type_int}, + + {0, 0} +}; + +static expr_type_t long_handle[] = { + {EQ, &type_int}, + {NE, &type_int}, + + {0, 0} +}; + +static expr_type_t *int_handle_x[ev_type_count] = { + [ev_int] = int_handle, +}; + +static expr_type_t *long_handle_x[ev_type_count] = { + [ev_long] = long_handle, +}; + +static expr_type_t **binary_expr_handle[ev_type_count] = { + [ev_int] = int_handle_x, + [ev_long] = long_handle_x, +}; + +static expr_type_t ***binary_expr_meta[ty_meta_count] = { + [ty_basic] = binary_expr_types, + [ty_enum] = binary_expr_types, + [ty_alias] = binary_expr_types, + [ty_handle] = binary_expr_handle, +}; + // supported operators for scalar-vector expressions static int scalar_vec_ops[] = { '*', '/', '%', MOD, 0 }; static const expr_t * @@ -1284,9 +1318,19 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2) et1 = low_level_type (t1); et2 = low_level_type (t2); - if (et1 >= ev_type_count || !binary_expr_types[et1]) + if (t1->meta >= ty_meta_count || !binary_expr_meta[t1->meta]) { return invalid_binary_expr(op, e1, e2); - if (et2 >= ev_type_count || !binary_expr_types[et1][et2]) + } + if (t2->meta >= ty_meta_count || !binary_expr_meta[t2->meta]) { + return invalid_binary_expr(op, e1, e2); + } + if (binary_expr_meta[t1->meta] != binary_expr_meta[t2->meta]) { + return invalid_binary_expr(op, e1, e2); + } + auto expr_meta = binary_expr_meta[t1->meta]; + if (et1 >= ev_type_count || !expr_meta[et1]) + return invalid_binary_expr(op, e1, e2); + if (et2 >= ev_type_count || !expr_meta[et1][et2]) return invalid_binary_expr(op, e1, e2); if ((t1->width > 1 || t2->width > 1)) { @@ -1372,7 +1416,7 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2) } } - expr_type = binary_expr_types[et1][et2]; + expr_type = expr_meta[et1][et2]; while (expr_type->op && expr_type->op != op) expr_type++; if (!expr_type->op) diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 01486c751..f3447c5fb 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -717,6 +717,8 @@ get_def_type (qfo_t *qfo, pr_ptr_t type) case ty_array: case ty_class: return ev_invalid; + case ty_meta_count: + break; } return ev_invalid; } @@ -757,6 +759,8 @@ get_type_size (qfo_t *qfo, pr_ptr_t type) case ty_class: case ty_algebra: return 0; // FIXME + case ty_meta_count: + break; } return 0; } @@ -807,6 +811,8 @@ get_type_alignment_log (qfo_t *qfo, pr_ptr_t type) case ty_class: case ty_algebra: return 0; // FIXME + case ty_meta_count: + break; } return 0; } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 3f2a332cb..b33751b88 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -156,7 +156,8 @@ int yylex (void); %token RETURN AT_RETURN ELLIPSIS %token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA %token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE -%token STRUCT HANDLE +%token STRUCT +%token HANDLE %token TYPE_SPEC TYPE_NAME TYPE_QUAL %token OBJECT_NAME %token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE @@ -164,6 +165,7 @@ int yylex (void); %type storage_class save_storage %type typespec typespec_reserved typespec_nonreserved +%type handle %type declspecs declspecs_nosc declspecs_nots %type declspecs_ts %type declspecs_nosc_ts declspecs_nosc_nots @@ -1122,9 +1124,10 @@ struct_specifier symtab_addsymbol (tab, sym); } } - | HANDLE tag + | handle tag { - symbol_t *sym = find_handle ($2, 0); + specifier_t spec = default_type ($1, 0); + symbol_t *sym = find_handle ($2, spec.type); sym->type = find_type (sym->type); $$ = make_spec (sym->type, 0, 0, 0); if (!sym->table) { @@ -1137,6 +1140,11 @@ struct_specifier } ; +handle + : HANDLE { $$ = make_spec (&type_int, 0, 0, 0); } + | HANDLE '(' TYPE_SPEC ')' { $$ = $3; } + ; + struct_list : '{' { diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index 3dfbdc2f1..07990f975 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -128,11 +128,15 @@ start_struct (int *su, symbol_t *tag, symtab_t *parent) symbol_t * find_handle (symbol_t *tag, type_t *type) { - symbol_t *sym = find_tag (ty_handle, tag, type); + if (type != &type_int && type != &type_long) { + error (0, "@handle type must be int or long"); + type = &type_int; + } + symbol_t *sym = find_tag (ty_handle, tag, 0); if (sym->type->type == ev_invalid) { - sym->type->type = ev_func; + sym->type->type = type->type; sym->type->width = 1; - sym->type->alignment = 1; + sym->type->alignment = type->alignment; } return sym; } diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 775c1e808..03d42a3ff 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -314,6 +314,7 @@ copy_chain (type_t *type, type_t *append) case ty_alias: //XXX is this correct? case ty_handle: case ty_algebra: + case ty_meta_count: internal_error (0, "copy object type %d", type->meta); } } @@ -373,6 +374,7 @@ append_type (type_t *type, type_t *new) case ty_alias: //XXX is this correct? case ty_handle: case ty_algebra: + case ty_meta_count: internal_error (0, "append to object type"); } } @@ -445,6 +447,8 @@ types_same (type_t *a, type_t *b) return a->name == b->name; case ty_algebra: return a->t.algebra == b->t.algebra; + case ty_meta_count: + break; } internal_error (0, "we be broke"); } @@ -578,6 +582,8 @@ find_type (type_t *type) break; case ty_algebra: break; + case ty_meta_count: + break; } } @@ -845,6 +851,8 @@ print_type_str (dstring_t *str, const type_t *type) return; } switch (type->meta) { + case ty_meta_count: + break; case ty_algebra: algebra_print_type_str (str, type); return; @@ -1040,6 +1048,8 @@ encode_type (dstring_t *encoding, const type_t *type) if (!type) return; switch (type->meta) { + case ty_meta_count: + break; case ty_algebra: algebra_encode_type (encoding, type); return; @@ -1424,6 +1434,8 @@ type_size (const type_t *type) return type_size (type->t.alias.aux_type); case ty_algebra: return algebra_type_size (type); + case ty_meta_count: + break; } internal_error (0, "invalid type meta: %d", type->meta); } @@ -1456,6 +1468,8 @@ type_width (const type_t *type) return type_width (type->t.alias.aux_type); case ty_algebra: return algebra_type_width (type); + case ty_meta_count: + break; } internal_error (0, "invalid type meta: %d", type->meta); }