mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 10:21:21 +00:00
[qfcc] Add some utility functions for working with vector types
Finding vector types from base type and width, and getting the base type for a vector type, as well as basic promotion rules for math types.
This commit is contained in:
parent
c120bf2940
commit
ae0b3a5870
3 changed files with 85 additions and 14 deletions
|
@ -160,6 +160,8 @@ type_t *find_type (type_t *new);
|
|||
void new_typedef (const char *name, type_t *type);
|
||||
type_t *field_type (type_t *aux);
|
||||
type_t *pointer_type (type_t *aux);
|
||||
type_t *vector_type (const type_t *ele_type, int width) __attribute__((pure));
|
||||
type_t *base_type (const type_t *vec_type) __attribute__((pure));
|
||||
type_t *array_type (type_t *aux, int size);
|
||||
type_t *based_array_type (type_t *aux, int base, int top);
|
||||
type_t *alias_type (type_t *type, type_t *alias_chain, const char *name);
|
||||
|
@ -187,6 +189,7 @@ int is_array (const type_t *type) __attribute__((pure));
|
|||
int is_structural (const type_t *type) __attribute__((pure));
|
||||
int type_compatible (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
int type_assignable (const type_t *dst, const type_t *src);
|
||||
int type_promotes (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
int type_same (const type_t *dst, const type_t *src) __attribute__((pure));
|
||||
int type_size (const type_t *type) __attribute__((pure));
|
||||
int type_width (const type_t *type) __attribute__((pure));
|
||||
|
@ -197,5 +200,7 @@ void chain_initial_types (void);
|
|||
void clear_typedefs (void);
|
||||
|
||||
extern type_t *ev_types[];
|
||||
extern int type_cast_map[];
|
||||
#define TYPE_CAST_CODE(from, to, width) (((width) << 6) | ((from) << 3) | (to))
|
||||
|
||||
#endif//__type_h
|
||||
|
|
|
@ -1760,17 +1760,6 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
|
|||
return sblock;
|
||||
}
|
||||
|
||||
static int type_map[ev_type_count] = {
|
||||
[ev_int] = 0,
|
||||
[ev_float] = 1,
|
||||
[ev_long] = 2,
|
||||
[ev_double] = 3,
|
||||
[ev_uint] = 4,
|
||||
//[ev_bool32] = 5,
|
||||
[ev_ulong] = 6,
|
||||
//[ev_bool64] = 7,
|
||||
};
|
||||
|
||||
static sblock_t *
|
||||
expr_cast (sblock_t *sblock, expr_t *e, operand_t **op)
|
||||
{
|
||||
|
@ -1786,10 +1775,10 @@ expr_cast (sblock_t *sblock, expr_t *e, operand_t **op)
|
|||
s = new_statement (st_expr, "conv", e);
|
||||
s->opa = src;
|
||||
if (options.code.progsversion == PROG_VERSION) {
|
||||
int from = type_map[src_type->type];
|
||||
int to = type_map[type->type];
|
||||
int from = type_cast_map[src_type->type];
|
||||
int to = type_cast_map[type->type];
|
||||
int width = type_width (src_type) - 1;
|
||||
int conv = (width << 6) | (from << 3) | to;
|
||||
int conv = TYPE_CAST_CODE (from, to, width);
|
||||
s->opb = short_operand (conv, e);
|
||||
}
|
||||
s->opc = *op;
|
||||
|
|
|
@ -89,6 +89,11 @@ type_t type_invalid = {
|
|||
};
|
||||
#include "tools/qfcc/include/vec_types.h"
|
||||
|
||||
#define VEC_TYPE(type_name, base_type) &type_##type_name,
|
||||
static type_t *vec_types[] = {
|
||||
#include "tools/qfcc/include/vec_types.h"
|
||||
0
|
||||
};
|
||||
type_t *type_nil;
|
||||
type_t *type_default;
|
||||
type_t *type_long_int;
|
||||
|
@ -145,6 +150,17 @@ type_t *ev_types[ev_type_count] = {
|
|||
&type_invalid,
|
||||
};
|
||||
|
||||
int type_cast_map[ev_type_count] = {
|
||||
[ev_int] = 0,
|
||||
[ev_float] = 1,
|
||||
[ev_long] = 2,
|
||||
[ev_double] = 3,
|
||||
[ev_uint] = 4,
|
||||
//[ev_bool32] = 5,
|
||||
[ev_ulong] = 6,
|
||||
//[ev_bool64] = 7,
|
||||
};
|
||||
|
||||
static type_t *types_freelist;
|
||||
|
||||
etype_t
|
||||
|
@ -524,6 +540,38 @@ pointer_type (type_t *aux)
|
|||
return new;
|
||||
}
|
||||
|
||||
type_t *
|
||||
vector_type (const type_t *ele_type, int width)
|
||||
{
|
||||
if (width == 1) {
|
||||
for (type_t **t = ev_types; t - ev_types < ev_type_count; t++) {
|
||||
if ((*t)->type == ele_type->type && (*t)->width == 1) {
|
||||
return *t;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (type_t **vtype = vec_types; *vtype; vtype++) {
|
||||
if ((*vtype)->type == ele_type->type
|
||||
&& (*vtype)->width == width) {
|
||||
return *vtype;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
type_t *
|
||||
base_type (const type_t *vec_type)
|
||||
{
|
||||
if (!is_math (vec_type)) {
|
||||
return 0;
|
||||
}
|
||||
// vec_type->type for quaternion and vector points back to itself
|
||||
if (is_quaternion (vec_type) || is_vector (vec_type)) {
|
||||
return &type_float;
|
||||
}
|
||||
return ev_types[vec_type->type];
|
||||
}
|
||||
|
||||
type_t *
|
||||
array_type (type_t *aux, int size)
|
||||
{
|
||||
|
@ -1097,6 +1145,35 @@ type_assignable (const type_t *dst, const type_t *src)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
type_promotes (const type_t *dst, const type_t *src)
|
||||
{
|
||||
dst = unalias_type (dst);
|
||||
src = unalias_type (src);
|
||||
// nothing promotes to int
|
||||
if (is_int (dst)) {
|
||||
return 0;
|
||||
}
|
||||
if (is_uint (dst) && is_int (src)) {
|
||||
return 1;
|
||||
}
|
||||
if (is_long (dst) && (is_int (src) || is_uint (src))) {
|
||||
return 1;
|
||||
}
|
||||
if (is_ulong (dst) && (is_int (src) || is_uint (src) || is_long (src))) {
|
||||
return 1;
|
||||
}
|
||||
if (is_float (dst) && (is_int (src) || is_uint (src))) {
|
||||
return 1;
|
||||
}
|
||||
//XXX what to do with (u)long<->float?
|
||||
// everything promotes to double
|
||||
if (is_double (dst)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
type_same (const type_t *dst, const type_t *src)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue