mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-25 22:01:33 +00:00
[qfcc] Support offset aliases of values
But explicitly not for pointers (even an offset of 0 breaks the pointer relocation).
This commit is contained in:
parent
b456f936c6
commit
73d1044bec
3 changed files with 31 additions and 3 deletions
|
@ -67,6 +67,8 @@ void value_store (pr_type_t *dst, const struct type_s *dstType,
|
|||
const struct expr_s *src);
|
||||
const char *get_value_string (const struct ex_value_s *value);
|
||||
|
||||
struct ex_value_s *offset_alias_value (struct ex_value_s *value,
|
||||
struct type_s *type, int offset);
|
||||
struct ex_value_s *alias_value (struct ex_value_s *value, struct type_s *type);
|
||||
struct def_s *emit_value (struct ex_value_s *value, struct def_s *def);
|
||||
struct def_s *emit_value_core (struct ex_value_s *value, struct def_s *def,
|
||||
|
|
|
@ -154,7 +154,7 @@ _print_operand (operand_t *op)
|
|||
printf ("%s", op->def->name);
|
||||
break;
|
||||
case op_value:
|
||||
printf ("(%s) %s", pr_type_name[op->type->type],
|
||||
printf ("(%s) %s", get_type_string (op->type),
|
||||
get_value_string (op->value));
|
||||
break;
|
||||
case op_label:
|
||||
|
@ -514,8 +514,18 @@ offset_alias_operand (type_t *type, int offset, operand_t *aop, expr_t *expr)
|
|||
def = def->alias;
|
||||
return def_operand (alias_def (def, type, offset), 0, expr);
|
||||
} else if (aop->op_type == op_value) {
|
||||
if (!is_ptr (aop->value->type)) {
|
||||
auto value = offset_alias_value (aop->value, type, offset);
|
||||
top = value_operand (value, expr);
|
||||
} else {
|
||||
// even an offset of 0 will break a pointer value because of
|
||||
// relocations
|
||||
if (offset) {
|
||||
internal_error (expr, "offset alias of pointer value operand");
|
||||
}
|
||||
top = value_operand (aop->value, expr);
|
||||
top->type = type;
|
||||
}
|
||||
return top;
|
||||
} else {
|
||||
internal_error (expr, "invalid alias target: %s: %s",
|
||||
|
|
|
@ -531,6 +531,22 @@ ReuseString (const char *str)
|
|||
return strpool_addstr (pr.strings, str);
|
||||
}
|
||||
|
||||
ex_value_t *
|
||||
offset_alias_value (ex_value_t *value, type_t *type, int offset)
|
||||
{
|
||||
if (type_size (type) > type_size (value->type)) {
|
||||
error (0, "unable to alias to a larger sized value");
|
||||
return value;
|
||||
}
|
||||
if (offset < 0 || offset + type_size (type) > type_size (value->type)) {
|
||||
error (0, "invalid offset");
|
||||
return value;
|
||||
}
|
||||
pr_type_t data[type_size (value->type)];
|
||||
memcpy (data, &value->v, sizeof (pr_type_t) * type_size (value->type));
|
||||
return new_type_value (type, data + offset);
|
||||
}
|
||||
|
||||
ex_value_t *
|
||||
alias_value (ex_value_t *value, type_t *type)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue