mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[qfcc] Fix adjusted swizzles for the same def
The singleton alias resulted in the adjusted swizzles being corrupted when for the same def. Other than adding properly sized swizzles (planned), the simplest solution is to (separately) allow alias that stick out from from the def.
This commit is contained in:
parent
29a57b7128
commit
a5304461dd
3 changed files with 28 additions and 17 deletions
|
@ -165,6 +165,9 @@ def_t *new_def (const char *name, struct type_s *type,
|
|||
\todo Make aliasing to the same type a no-op?
|
||||
*/
|
||||
def_t *alias_def (def_t *def, struct type_s *type, int offset);
|
||||
//FIXME this probably shouldn't exist (it's for swizzles, so doing proper
|
||||
//multi-width swizzles will remove the need for it)
|
||||
def_t *cover_alias_def (def_t *def, struct type_s *type, int offset);
|
||||
|
||||
/** Free a def.
|
||||
|
||||
|
|
|
@ -179,20 +179,12 @@ new_def (const char *name, type_t *type, defspace_t *space,
|
|||
}
|
||||
|
||||
def_t *
|
||||
alias_def (def_t *def, type_t *type, int offset)
|
||||
cover_alias_def (def_t *def, type_t *type, int offset)
|
||||
{
|
||||
def_t *alias;
|
||||
|
||||
if (def->alias) {
|
||||
expr_t e;
|
||||
e.file = def->file;
|
||||
e.line = def->line;
|
||||
internal_error (&e, "aliasing an alias def");
|
||||
}
|
||||
if (type_size (type) > type_size (def->type))
|
||||
internal_error (0, "aliasing a def to a larger type");
|
||||
if (offset < 0 || offset + type_size (type) > type_size (def->type))
|
||||
internal_error (0, "invalid alias offset");
|
||||
if (offset + type_size (type) <= 0 || offset >= type_size (def->type))
|
||||
internal_error (0, "invalid cover offset");
|
||||
for (alias = def->alias_defs; alias; alias = alias->next) {
|
||||
if (alias->type == type && alias->offset == offset)
|
||||
return alias;
|
||||
|
@ -212,6 +204,22 @@ alias_def (def_t *def, type_t *type, int offset)
|
|||
return alias;
|
||||
}
|
||||
|
||||
def_t *
|
||||
alias_def (def_t *def, type_t *type, int offset)
|
||||
{
|
||||
if (def->alias) {
|
||||
expr_t e;
|
||||
e.file = def->file;
|
||||
e.line = def->line;
|
||||
internal_error (&e, "aliasing an alias def");
|
||||
}
|
||||
if (type_size (type) > type_size (def->type))
|
||||
internal_error (0, "aliasing a def to a larger type");
|
||||
if (offset < 0 || offset + type_size (type) > type_size (def->type))
|
||||
internal_error (0, "invalid alias offset");
|
||||
return cover_alias_def (def, type, offset);
|
||||
}
|
||||
|
||||
def_t *
|
||||
temp_def (type_t *type)
|
||||
{
|
||||
|
|
|
@ -191,11 +191,11 @@ cover_def_32 (def_t *def, int *adj)
|
|||
*adj = offset & 3;
|
||||
if (offset & 3) {
|
||||
if (def->alias) {
|
||||
cover = alias_def (def->alias, def->type, def->offset);
|
||||
cover = cover_alias_def (def->alias, def->type,
|
||||
def->offset - (offset & 3));
|
||||
} else {
|
||||
cover = alias_def (def, def->type, 0);
|
||||
cover = cover_alias_def (def, def->type, -(offset & 3));
|
||||
}
|
||||
cover->offset -= offset & 3;
|
||||
}
|
||||
return cover;
|
||||
}
|
||||
|
@ -215,11 +215,11 @@ cover_def_64 (def_t *def, int *adj)
|
|||
*adj = (offset & 6) >> 1;
|
||||
if (offset & 6) {
|
||||
if (def->alias) {
|
||||
cover = alias_def (def->alias, def->type, def->offset);
|
||||
cover = cover_alias_def (def->alias, def->type,
|
||||
def->offset - (offset & 6));
|
||||
} else {
|
||||
cover = alias_def (def, def->type, 0);
|
||||
cover = cover_alias_def (def, def->type, -(offset & 6));
|
||||
}
|
||||
cover->offset -= offset & 6;
|
||||
}
|
||||
return cover;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue