mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-23 10:50:58 +00:00
[qfcc] Add types for ivec3/4 and vec3/4
Needed to get quaternions and vectors going. I'll add more later.
This commit is contained in:
parent
c467217b4b
commit
feb3be4e6b
6 changed files with 248 additions and 46 deletions
|
@ -60,6 +60,9 @@ typedef struct type_s {
|
|||
etype_t type; ///< ev_invalid means structure/array etc
|
||||
const char *name;
|
||||
int alignment; ///< required alignment for instances
|
||||
int width; ///< components in vector types, otherwise 1
|
||||
///< vector and quaternion are 1 (separate from
|
||||
///< vec3 and vec4)
|
||||
/// function/pointer/array/struct types are more complex
|
||||
ty_meta_e meta;
|
||||
union {
|
||||
|
@ -99,6 +102,11 @@ typedef struct {
|
|||
#define EV_TYPE(type) extern type_t type_##type;
|
||||
#include "QF/progs/pr_type_names.h"
|
||||
|
||||
extern type_t type_ivec3;
|
||||
extern type_t type_ivec4;
|
||||
extern type_t type_vec3;
|
||||
extern type_t type_vec4;
|
||||
|
||||
extern type_t type_invalid;
|
||||
extern type_t type_floatfield;
|
||||
|
||||
|
@ -158,6 +166,7 @@ const char *type_get_encoding (const type_t *type);
|
|||
int is_enum (const type_t *type) __attribute__((pure));
|
||||
int is_integral (const type_t *type) __attribute__((pure));
|
||||
int is_scalar (const type_t *type) __attribute__((pure));
|
||||
int is_nonscalar (const type_t *type) __attribute__((pure));
|
||||
int is_math (const type_t *type) __attribute__((pure));
|
||||
int is_struct (const type_t *type) __attribute__((pure));
|
||||
int is_array (const type_t *type) __attribute__((pure));
|
||||
|
|
|
@ -71,33 +71,114 @@ static hashtab_t *static_instances;
|
|||
static hashtab_t *static_instance_classes;
|
||||
|
||||
// these will be built up further
|
||||
type_t type_selector = { ev_invalid, 0, 0, ty_struct};
|
||||
type_t type_SEL = { ev_ptr, "SEL", 1, ty_basic, {{&type_selector}}};
|
||||
type_t *IMP_params[] = {&type_id, &type_SEL};
|
||||
type_t type_IMP = { ev_func, "IMP", 1, ty_basic,
|
||||
{{&type_id, -3, IMP_params}}};
|
||||
type_t type_super = { ev_invalid, 0, 0 };
|
||||
type_t type_SuperPtr = { ev_ptr, 0, 1, ty_basic, {{&type_super}}};
|
||||
type_t *supermsg_params[] = {&type_SuperPtr, &type_SEL};
|
||||
type_t type_supermsg = { ev_func, ".supermsg", 1, ty_basic,
|
||||
{{&type_id, -3, supermsg_params}}};
|
||||
type_t type_method = { ev_invalid, 0, 0, ty_struct };
|
||||
type_t type_method_description = { ev_invalid, 0, 0, ty_struct };
|
||||
type_t type_category = { ev_invalid, 0, 0, ty_struct};
|
||||
type_t type_ivar = { ev_invalid, 0, 0, ty_struct};
|
||||
type_t type_module = { ev_invalid, 0, 0, ty_struct};
|
||||
type_t type_moduleptr = { ev_ptr, 0, 1, ty_basic, {{&type_module}}};
|
||||
type_t *obj_exec_class_params[] = { &type_moduleptr };
|
||||
type_t type_exec_class = { ev_func, 0, 1, ty_basic,
|
||||
{{&type_void, 1, obj_exec_class_params}}};
|
||||
type_t type_selector = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_SEL = {
|
||||
.type = ev_ptr,
|
||||
.name = "SEL",
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_selector}},
|
||||
};
|
||||
type_t *IMP_params[] = { &type_id, &type_SEL };
|
||||
type_t type_IMP = {
|
||||
.type = ev_func,
|
||||
.name = "IMP",
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_id, -3, IMP_params}},
|
||||
};
|
||||
type_t type_super = {
|
||||
.type = ev_invalid,
|
||||
};
|
||||
type_t type_SuperPtr = {
|
||||
.type = ev_ptr,
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_super}},
|
||||
};
|
||||
type_t *supermsg_params[] = { &type_SuperPtr, &type_SEL };
|
||||
type_t type_supermsg = {
|
||||
.type = ev_func,
|
||||
.name = ".supermsg",
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_id, -3, supermsg_params}},
|
||||
};
|
||||
type_t type_method = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_method_description = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_category = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_ivar = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_module = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_moduleptr = {
|
||||
.type = ev_ptr,
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_module}},
|
||||
};
|
||||
type_t *obj_exec_class_params[] = {
|
||||
&type_moduleptr,
|
||||
};
|
||||
type_t type_exec_class = {
|
||||
.type = ev_func,
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_void, 1, obj_exec_class_params}},
|
||||
};
|
||||
// the cast of 1 in the init is to ensure pointers to incomplete types
|
||||
// are never misidentified as id. It will be set to the correct value
|
||||
// when the obj system is initialized.
|
||||
type_t type_object = {ev_invalid, 0, 0, ty_struct, {{(type_t *)1}}};
|
||||
type_t type_id = { ev_ptr, "id", 1, ty_basic, {{&type_object}}};
|
||||
type_t type_class = { ev_invalid, 0, 0, ty_struct};
|
||||
type_t type_Class = { ev_ptr, 0, 1, ty_basic, {{&type_class}}};
|
||||
type_t type_protocol = { ev_invalid, 0, 0, ty_struct};
|
||||
type_t type_object = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
{{(type_t *)1}},
|
||||
};
|
||||
type_t type_id = {
|
||||
.type = ev_ptr,
|
||||
.name = "id",
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_object}},
|
||||
};
|
||||
type_t type_class = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_Class = {
|
||||
.type = ev_ptr,
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_class}},
|
||||
};
|
||||
type_t type_protocol = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
|
||||
int obj_initialized = 0;
|
||||
|
||||
|
|
|
@ -185,6 +185,7 @@ parse_params (type_t *type, param_t *parms)
|
|||
new = new_type ();
|
||||
new->type = ev_func;
|
||||
new->alignment = 1;
|
||||
new->width = 1;
|
||||
new->t.func.type = type;
|
||||
new->t.func.num_params = 0;
|
||||
|
||||
|
|
|
@ -230,12 +230,32 @@ v6p_opcode_find (const char *name, operand_t *op_a, operand_t *op_b,
|
|||
return op;
|
||||
}
|
||||
|
||||
static etype_t
|
||||
operand_type (operand_t *op)
|
||||
{
|
||||
if (!op) {
|
||||
return ev_invalid;
|
||||
}
|
||||
etype_t type = low_level_type (op->type);
|
||||
if (type == ev_vector || type == ev_quaternion) {
|
||||
return ev_float;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static int
|
||||
operand_width (operand_t *op)
|
||||
{
|
||||
if (!op) {
|
||||
return 0;
|
||||
}
|
||||
etype_t type = low_level_type (op->type);
|
||||
if (type == ev_vector) {
|
||||
return 3;
|
||||
}
|
||||
if (type == ev_quaternion) {
|
||||
return 4;
|
||||
}
|
||||
return op->width;
|
||||
}
|
||||
|
||||
|
@ -246,9 +266,9 @@ rua_opcode_find (const char *name, operand_t *op_a, operand_t *op_b,
|
|||
opcode_t search_op = {
|
||||
.opname = name,
|
||||
.types = {
|
||||
op_a ? low_level_type (op_a->type) : ev_invalid,
|
||||
op_b ? low_level_type (op_b->type) : ev_invalid,
|
||||
op_c ? low_level_type (op_c->type) : ev_invalid,
|
||||
operand_type (op_a),
|
||||
operand_type (op_b),
|
||||
operand_type (op_c),
|
||||
},
|
||||
.widths = {
|
||||
operand_width (op_a),
|
||||
|
|
|
@ -194,6 +194,8 @@ start_enum (symbol_t *sym)
|
|||
sym = find_enum (0);
|
||||
}
|
||||
sym->type->t.symtab = new_symtab (current_symtab, stab_local);
|
||||
sym->type->alignment = 1;
|
||||
sym->type->width = 1;
|
||||
return sym->type->t.symtab;
|
||||
}
|
||||
|
||||
|
@ -207,7 +209,6 @@ finish_enum (symbol_t *sym)
|
|||
|
||||
enum_type = sym->type = find_type (sym->type);
|
||||
enum_tab = enum_type->t.symtab;
|
||||
enum_type->alignment = 1;
|
||||
|
||||
for (name = enum_tab->symbols; name; name = name->next) {
|
||||
name->type = sym->type;
|
||||
|
|
|
@ -65,6 +65,8 @@
|
|||
.type = ev_##t, \
|
||||
.name = #t, \
|
||||
.alignment = PR_ALIGNOF(t), \
|
||||
.width = __builtin_choose_expr (ev_##t == ev_short \
|
||||
|| ev_##t == ev_ushort, 0, 1), \
|
||||
.meta = ty_basic, \
|
||||
{{ __builtin_choose_expr (ev_##t == ev_field \
|
||||
|| ev_##t == ev_func \
|
||||
|
@ -72,7 +74,23 @@
|
|||
};
|
||||
#include "QF/progs/pr_type_names.h"
|
||||
|
||||
type_t type_invalid = { ev_invalid, "invalid" };
|
||||
type_t type_invalid = {
|
||||
.type = ev_invalid,
|
||||
.name = "invalid",
|
||||
};
|
||||
|
||||
#define VTYPE(t, b) \
|
||||
type_t type_##t = { \
|
||||
.type = ev_##b, \
|
||||
.name = #t, \
|
||||
.alignment = PR_ALIGNOF(t), \
|
||||
.width = PR_SIZEOF(t) / PR_SIZEOF (b), \
|
||||
.meta = ty_basic, \
|
||||
};
|
||||
VTYPE(ivec3, int)
|
||||
VTYPE(ivec4, int)
|
||||
VTYPE(vec3, float)
|
||||
VTYPE(vec4, float)
|
||||
|
||||
type_t *type_nil;
|
||||
type_t *type_default;
|
||||
|
@ -80,17 +98,49 @@ type_t *type_long_int;
|
|||
type_t *type_ulong_uint;
|
||||
|
||||
// these will be built up further
|
||||
type_t type_va_list = { ev_invalid, 0, 0, ty_struct };
|
||||
type_t type_param = { ev_invalid, 0, 0, ty_struct };
|
||||
type_t type_zero = { ev_invalid, 0, 0, ty_struct };
|
||||
type_t type_type_encodings = { ev_invalid, "@type_encodings", 0,
|
||||
ty_struct };
|
||||
type_t type_xdef = { ev_invalid, "@xdef", 0, ty_struct };
|
||||
type_t type_xdef_pointer = { ev_ptr, 0, 1, ty_basic, {{&type_xdef}} };
|
||||
type_t type_xdefs = { ev_invalid, "@xdefs", 0, ty_struct };
|
||||
type_t type_va_list = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_param = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_zero = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_type_encodings = {
|
||||
.type = ev_invalid,
|
||||
.name = "@type_encodings",
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_xdef = {
|
||||
.type = ev_invalid,
|
||||
.name = "@xdef",
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_xdef_pointer = {
|
||||
.type = ev_ptr,
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_xdef}},
|
||||
};
|
||||
type_t type_xdefs = {
|
||||
.type = ev_invalid,
|
||||
.name = "@xdefs",
|
||||
.meta = ty_struct,
|
||||
};
|
||||
|
||||
type_t type_floatfield = { ev_field, ".float", 1, ty_basic,
|
||||
{{&type_float}} };
|
||||
type_t type_floatfield = {
|
||||
.type = ev_field,
|
||||
.name = ".float",
|
||||
.alignment = 1,
|
||||
.width = 1,
|
||||
.meta = ty_basic,
|
||||
{{&type_float}},
|
||||
};
|
||||
|
||||
#define EV_TYPE(type) &type_##type,
|
||||
type_t *ev_types[ev_type_count] = {
|
||||
|
@ -280,10 +330,12 @@ append_type (type_t *type, type_t *new)
|
|||
case ev_ptr:
|
||||
t = &(*t)->t.fldptr.type;
|
||||
type->alignment = 1;
|
||||
type->width = 1;
|
||||
break;
|
||||
case ev_func:
|
||||
t = &(*t)->t.func.type;
|
||||
type->alignment = 1;
|
||||
type->width = 1;
|
||||
break;
|
||||
case ev_invalid:
|
||||
internal_error (0, "invalid basic type");
|
||||
|
@ -293,6 +345,7 @@ append_type (type_t *type, type_t *new)
|
|||
case ty_array:
|
||||
t = &(*t)->t.array.type;
|
||||
type->alignment = new->alignment;
|
||||
type->width = new->width;
|
||||
break;
|
||||
case ty_struct:
|
||||
case ty_union:
|
||||
|
@ -339,7 +392,7 @@ types_same (type_t *a, type_t *b)
|
|||
return 0;
|
||||
return 1;
|
||||
default: // other types don't have aux data
|
||||
return 1;
|
||||
return a->width == b->width;
|
||||
}
|
||||
break;
|
||||
case ty_struct:
|
||||
|
@ -447,6 +500,7 @@ field_type (type_t *aux)
|
|||
new = new_type ();
|
||||
new->type = ev_field;
|
||||
new->alignment = 1;
|
||||
new->width = 1;
|
||||
if (aux) {
|
||||
new = find_type (append_type (new, aux));
|
||||
}
|
||||
|
@ -465,6 +519,7 @@ pointer_type (type_t *aux)
|
|||
new = new_type ();
|
||||
new->type = ev_ptr;
|
||||
new->alignment = 1;
|
||||
new->width = 1;
|
||||
if (aux) {
|
||||
new = find_type (append_type (new, aux));
|
||||
}
|
||||
|
@ -485,6 +540,7 @@ array_type (type_t *aux, int size)
|
|||
new->type = ev_invalid;
|
||||
if (aux) {
|
||||
new->alignment = aux->alignment;
|
||||
new->width = aux->width;
|
||||
}
|
||||
new->t.array.size = size;
|
||||
if (aux) {
|
||||
|
@ -506,6 +562,7 @@ based_array_type (type_t *aux, int base, int top)
|
|||
new->type = ev_invalid;
|
||||
if (aux) {
|
||||
new->alignment = aux->alignment;
|
||||
new->width = aux->width;
|
||||
}
|
||||
new->meta = ty_array;
|
||||
new->t.array.type = aux;
|
||||
|
@ -523,6 +580,7 @@ alias_type (type_t *type, type_t *alias_chain, const char *name)
|
|||
alias->meta = ty_alias;
|
||||
alias->type = type->type;
|
||||
alias->alignment = type->alignment;
|
||||
alias->width = type->width;
|
||||
if (type == alias_chain && type->meta == ty_alias) {
|
||||
// typedef of a type that contains a typedef somewhere
|
||||
// grab the alias-free branch for type
|
||||
|
@ -868,6 +926,23 @@ int
|
|||
is_scalar (const type_t *type)
|
||||
{
|
||||
type = unalias_type (type);
|
||||
if (is_short (type) || is_ushort (type)) {
|
||||
// shorts have width 0
|
||||
return 1;
|
||||
}
|
||||
if (type->width != 1) {
|
||||
return 0;
|
||||
}
|
||||
return is_float (type) || is_integral (type) || is_double (type);
|
||||
}
|
||||
|
||||
int
|
||||
is_nonscalar (const type_t *type)
|
||||
{
|
||||
type = unalias_type (type);
|
||||
if (type->width < 2) {
|
||||
return 0;
|
||||
}
|
||||
return is_float (type) || is_integral (type) || is_double (type);
|
||||
}
|
||||
|
||||
|
@ -875,9 +950,11 @@ int
|
|||
is_math (const type_t *type)
|
||||
{
|
||||
type = unalias_type (type);
|
||||
etype_t t = type->type;
|
||||
|
||||
return t == ev_vector || t == ev_quaternion || is_scalar (type);
|
||||
if (is_vector (type) || is_quaternion (type)) {
|
||||
return 1;
|
||||
}
|
||||
return is_scalar (type) || is_nonscalar (type);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -981,7 +1058,7 @@ type_size (const type_t *type)
|
|||
{
|
||||
switch (type->meta) {
|
||||
case ty_basic:
|
||||
return pr_type_size[type->type];
|
||||
return pr_type_size[type->type] * type->width;
|
||||
case ty_struct:
|
||||
case ty_union:
|
||||
if (!type->t.symtab)
|
||||
|
@ -1015,10 +1092,13 @@ type_width (const type_t *type)
|
|||
{
|
||||
switch (type->meta) {
|
||||
case ty_basic:
|
||||
if (type->type == ev_ushort || type->type == ev_short) {
|
||||
return 0;
|
||||
if (type->type == ev_vector) {
|
||||
return 3;
|
||||
}
|
||||
return 1; //FIXME vector should be 3
|
||||
if (type->type == ev_quaternion) {
|
||||
return 4;
|
||||
}
|
||||
return type->width;
|
||||
case ty_struct:
|
||||
case ty_union:
|
||||
return 1;
|
||||
|
@ -1050,11 +1130,21 @@ chain_basic_types (void)
|
|||
chain_type (&type_ptr);
|
||||
chain_type (&type_floatfield);
|
||||
if (!options.traditional) {
|
||||
if (options.code.progsversion == PROG_VERSION) {
|
||||
type_quaternion.alignment = 4;
|
||||
}
|
||||
chain_type (&type_quaternion);
|
||||
chain_type (&type_int);
|
||||
chain_type (&type_uint);
|
||||
chain_type (&type_short);
|
||||
chain_type (&type_double);
|
||||
|
||||
if (options.code.progsversion == PROG_VERSION) {
|
||||
chain_type (&type_ivec3);
|
||||
chain_type (&type_ivec4);
|
||||
chain_type (&type_vec3);
|
||||
chain_type (&type_vec4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue