mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
pr_*: add storep.p so pointers can be stored into entities
emit.c: convert & (address) to . in unary . rewrite emit_assign_expr expr.c: remove debug code and make unary . less agressive on address calcs also convert & (address) to . for lvals
This commit is contained in:
parent
b56d7f3248
commit
8ddce20949
5 changed files with 50 additions and 76 deletions
|
@ -242,6 +242,7 @@ typedef enum {
|
||||||
|
|
||||||
OP_LOAD_P,
|
OP_LOAD_P,
|
||||||
OP_STORE_P,
|
OP_STORE_P,
|
||||||
|
OP_STOREP_P,
|
||||||
} pr_opcode_e;
|
} pr_opcode_e;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -464,6 +464,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
case OP_STOREP_S:
|
case OP_STOREP_S:
|
||||||
case OP_STOREP_FNC: // pointers
|
case OP_STOREP_FNC: // pointers
|
||||||
case OP_STOREP_I:
|
case OP_STOREP_I:
|
||||||
|
case OP_STOREP_P:
|
||||||
//FIXME put bounds checking back
|
//FIXME put bounds checking back
|
||||||
ptr = pr->pr_globals + OPB.integer_var;
|
ptr = pr->pr_globals + OPB.integer_var;
|
||||||
ptr->integer_var = OPA.integer_var;
|
ptr->integer_var = OPA.integer_var;
|
||||||
|
|
|
@ -142,6 +142,7 @@ opcode_t pr_opcodes[] = {
|
||||||
{".=", "storep.fld", OP_STOREP_FLD, true, ev_field, ev_pointer, ev_void, PROG_ID_VERSION},
|
{".=", "storep.fld", OP_STOREP_FLD, true, ev_field, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||||
{".=", "storep.fnc", OP_STOREP_FNC, true, ev_func, ev_pointer, ev_void, PROG_ID_VERSION},
|
{".=", "storep.fnc", OP_STOREP_FNC, true, ev_func, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||||
{".=", "storep.i", OP_STOREP_I, true, ev_integer, ev_pointer, ev_void, PROG_VERSION},
|
{".=", "storep.i", OP_STOREP_I, true, ev_integer, ev_pointer, ev_void, PROG_VERSION},
|
||||||
|
{".=", "storep.p", OP_STOREP_P, true, ev_pointer, ev_pointer, ev_void, PROG_VERSION},
|
||||||
|
|
||||||
{".=", "storeb.f", OP_STOREB_F, true, ev_float, ev_pointer, ev_integer, PROG_VERSION},
|
{".=", "storeb.f", OP_STOREB_F, true, ev_float, ev_pointer, ev_integer, PROG_VERSION},
|
||||||
{".=", "storeb.v", OP_STOREB_V, true, ev_vector, ev_pointer, ev_integer, PROG_VERSION},
|
{".=", "storeb.v", OP_STOREB_V, true, ev_vector, ev_pointer, ev_integer, PROG_VERSION},
|
||||||
|
|
|
@ -166,43 +166,20 @@ emit_function_call (expr_t *e, def_t *dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
def_t *
|
def_t *
|
||||||
emit_assign_expr (const char *operator, expr_t *e)
|
emit_assign_expr (int oper, expr_t *e)
|
||||||
{
|
{
|
||||||
def_t *def_a, *def_b, *def_c;
|
def_t *def_a, *def_b, *def_c;
|
||||||
opcode_t *op;
|
opcode_t *op;
|
||||||
expr_t *e1 = e->e.expr.e1;
|
expr_t *e1 = e->e.expr.e1;
|
||||||
expr_t *e2 = e->e.expr.e2;
|
expr_t *e2 = e->e.expr.e2;
|
||||||
|
const char *operator = get_op_string (oper);
|
||||||
|
|
||||||
if (e1->type == ex_temp && e1->e.temp.users < 2) {
|
if (e1->type == ex_temp && e1->e.temp.users < 2) {
|
||||||
e1->e.temp.users--;
|
e1->e.temp.users--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (e1->type == ex_expr && e1->e.expr.op == '.'
|
if (oper == '=') {
|
||||||
&& extract_type (e1->e.expr.e1) == ev_pointer) {
|
|
||||||
def_a = emit_sub_expr (e2, 0);
|
|
||||||
def_c = emit_sub_expr (e1->e.expr.e2, 0);
|
|
||||||
def_b = emit_sub_expr (e1->e.expr.e1, 0);
|
|
||||||
op = PR_Opcode_Find (operator, def_a, def_b, def_c);
|
|
||||||
emit_statement (e->line, op, def_a, def_b, def_c);
|
|
||||||
} else {
|
|
||||||
def_a = emit_sub_expr (e1, 0);
|
def_a = emit_sub_expr (e1, 0);
|
||||||
if (def_a->type->type == ev_pointer
|
|
||||||
&& e2->type != ex_uexpr
|
|
||||||
&& e2->e.expr.op != '&') {
|
|
||||||
def_b = emit_sub_expr (e2, 0);
|
|
||||||
if (def_b->type->type == ev_pointer) {
|
|
||||||
expr_t *zero = new_expr ();
|
|
||||||
def_t *z;
|
|
||||||
|
|
||||||
zero->type = ex_short;
|
|
||||||
z = emit_sub_expr (zero, 0);
|
|
||||||
op = PR_Opcode_Find (operator, def_b, def_a, z);
|
|
||||||
emit_statement (e->line, op, def_b, def_a, z);
|
|
||||||
} else {
|
|
||||||
op = PR_Opcode_Find (operator, def_b, def_a, &def_void);
|
|
||||||
emit_statement (e->line, op, def_b, def_a, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (def_a->constant) {
|
if (def_a->constant) {
|
||||||
if (options.code.cow) {
|
if (options.code.cow) {
|
||||||
int size = pr_type_size[def_a->type->type];
|
int size = pr_type_size[def_a->type->type];
|
||||||
|
@ -218,22 +195,23 @@ emit_assign_expr (const char *operator, expr_t *e)
|
||||||
error (e1, "assignment to constant %s", def_a->name);
|
error (e1, "assignment to constant %s", def_a->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e2->type == ex_expr && e2->e.expr.type->type == ev_pointer
|
|
||||||
&& e2->e.expr.op == '&') {
|
|
||||||
//def_b = emit_sub_expr (e2->e.expr.e1, 0);
|
|
||||||
//e2 = e2->e.expr.e2;
|
|
||||||
//operator = ".";
|
|
||||||
//def_b = emit_sub_expr (e2, def_b);
|
|
||||||
e2->e.expr.op = '.';
|
|
||||||
def_b = emit_sub_expr (e2, def_a);
|
def_b = emit_sub_expr (e2, def_a);
|
||||||
} else {
|
|
||||||
def_b = emit_sub_expr (e2, def_a);
|
|
||||||
}
|
|
||||||
if (def_b != def_a) {
|
if (def_b != def_a) {
|
||||||
op = PR_Opcode_Find (operator, def_b, def_a, &def_void);
|
op = PR_Opcode_Find (operator, def_b, def_a, &def_void);
|
||||||
emit_statement (e->line, op, def_b, def_a, 0);
|
emit_statement (e->line, op, def_b, def_a, 0);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
def_b = emit_sub_expr (e2, 0);
|
||||||
|
if (e1->type == ex_expr && extract_type (e1->e.expr.e1) == ev_pointer) {
|
||||||
|
def_a = emit_sub_expr (e1->e.expr.e1, 0);
|
||||||
|
def_c = emit_sub_expr (e1->e.expr.e2, 0);
|
||||||
|
op = PR_Opcode_Find (operator, def_b, def_a, def_c);
|
||||||
|
} else {
|
||||||
|
def_a = emit_sub_expr (e1, 0);
|
||||||
|
def_c = 0;
|
||||||
|
op = PR_Opcode_Find (operator, def_b, def_a, &def_void);
|
||||||
}
|
}
|
||||||
|
emit_statement (e->line, op, def_b, def_a, def_c);
|
||||||
}
|
}
|
||||||
if (def_a->type->type != ev_pointer)
|
if (def_a->type->type != ev_pointer)
|
||||||
return def_a;
|
return def_a;
|
||||||
|
@ -289,8 +267,8 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
||||||
d = emit_function_call (e, dest);
|
d = emit_function_call (e, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (e->e.expr.op == '=') {
|
if (e->e.expr.op == '=' || e->e.expr.op == PAS) {
|
||||||
d = emit_assign_expr ("=", e);
|
d = emit_assign_expr (e->e.expr.op, e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (e->e.expr.e1->type == ex_block
|
if (e->e.expr.e1->type == ex_block
|
||||||
|
@ -358,6 +336,9 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
||||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||||
dest->users += 2;
|
dest->users += 2;
|
||||||
}
|
}
|
||||||
|
if (e->e.expr.e1->type == ex_expr
|
||||||
|
&& e->e.expr.e1->e.expr.op == '&')
|
||||||
|
e->e.expr.e1->e.expr.op = '.';
|
||||||
d = emit_sub_expr (e->e.expr.e1, dest);
|
d = emit_sub_expr (e->e.expr.e1, dest);
|
||||||
if (!d->name)
|
if (!d->name)
|
||||||
d->type = e->e.expr.type;
|
d->type = e->e.expr.type;
|
||||||
|
@ -454,7 +435,7 @@ emit_expr (expr_t *e)
|
||||||
switch (e->e.expr.op) {
|
switch (e->e.expr.op) {
|
||||||
case PAS:
|
case PAS:
|
||||||
case '=':
|
case '=':
|
||||||
emit_assign_expr (get_op_string (e->e.expr.op), e);
|
emit_assign_expr (e->e.expr.op, e);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
emit_branch (e->line, op_ifnot, e->e.expr.e1, e->e.expr.e2);
|
emit_branch (e->line, op_ifnot, e->e.expr.e1, e->e.expr.e2);
|
||||||
|
|
|
@ -1331,15 +1331,15 @@ unary_expr (int op, expr_t *e)
|
||||||
case '.':
|
case '.':
|
||||||
if (extract_type (e) != ev_pointer)
|
if (extract_type (e) != ev_pointer)
|
||||||
return error (e, "invalid type for unary .");
|
return error (e, "invalid type for unary .");
|
||||||
if (e->type == ex_expr && e->e.expr.op == '&'
|
//if (e->type == ex_expr && e->e.expr.op == '&'
|
||||||
&& (extract_type (e->e.expr.e1) == ev_entity
|
// && (extract_type (e->e.expr.e1) == ev_entity
|
||||||
|| extract_type (e->e.expr.e1) == ev_pointer)) {
|
// || extract_type (e->e.expr.e1) == ev_pointer)) {
|
||||||
e->e.expr.op = '.';
|
// e->e.expr.op = '.';
|
||||||
e->e.expr.type = e->e.expr.type->aux_type;
|
// e->e.expr.type = e->e.expr.type->aux_type;
|
||||||
} else {
|
//} else {
|
||||||
e = new_unary_expr ('.', e);
|
e = new_unary_expr ('.', e);
|
||||||
e->e.expr.type = get_type (e->e.expr.e1)->aux_type;
|
e->e.expr.type = get_type (e->e.expr.e1)->aux_type;
|
||||||
}
|
//}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
error (e, "internal error");
|
error (e, "internal error");
|
||||||
|
@ -1606,7 +1606,6 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
||||||
if (!t)
|
if (!t)
|
||||||
t = get_type (e1);
|
t = get_type (e1);
|
||||||
|
|
||||||
// print_expr (e1);puts("");
|
|
||||||
switch (e1->type) {
|
switch (e1->type) {
|
||||||
case ex_def:
|
case ex_def:
|
||||||
type = e1->e.def->type;
|
type = e1->e.def->type;
|
||||||
|
@ -1629,9 +1628,6 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
||||||
e = e1;
|
e = e1;
|
||||||
e->e.expr.op = '&';
|
e->e.expr.op = '&';
|
||||||
e->e.expr.type = pointer_type (e->e.expr.type);
|
e->e.expr.type = pointer_type (e->e.expr.type);
|
||||||
print_expr (e);puts("");
|
|
||||||
printf ("%s %s\n", pr_type_name[e->e.expr.type->type],
|
|
||||||
pr_type_name[e->e.expr.type->aux_type->type]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return error (e1, "invalid type for unary &");
|
return error (e1, "invalid type for unary &");
|
||||||
|
@ -1653,18 +1649,13 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
||||||
if (e->type == ex_pointer && e2->type == ex_short) {
|
if (e->type == ex_pointer && e2->type == ex_short) {
|
||||||
e->e.pointer.val += e2->e.short_val;
|
e->e.pointer.val += e2->e.short_val;
|
||||||
} else {
|
} else {
|
||||||
// print_expr (e); puts("");
|
|
||||||
// print_expr (e2); puts("");
|
|
||||||
if (e2->type != ex_short || e2->e.short_val) {
|
if (e2->type != ex_short || e2->e.short_val) {
|
||||||
// print_expr (e2);puts("");
|
|
||||||
e = new_binary_expr ('&', e, e2);
|
e = new_binary_expr ('&', e, e2);
|
||||||
}
|
}
|
||||||
if (e->type == ex_expr || e->type == ex_uexpr)
|
if (e->type == ex_expr || e->type == ex_uexpr)
|
||||||
e->e.expr.type = pointer_type (t);
|
e->e.expr.type = pointer_type (t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// print_expr (e);puts("");
|
|
||||||
// puts("");
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1718,9 +1709,6 @@ assign_expr (expr_t *e1, expr_t *e2)
|
||||||
return type_mismatch (e1, e2, op);
|
return type_mismatch (e1, e2, op);
|
||||||
else
|
else
|
||||||
type = t1;
|
type = t1;
|
||||||
//print_expr (e1); printf(" %d\n", e1->line);
|
|
||||||
//print_expr (e2); printf("\n");
|
|
||||||
//printf ("%s %s\n", pr_type_name[t1->type], pr_type_name[t2->type]);
|
|
||||||
if (is_indirect (e1) && is_indirect (e2)) {
|
if (is_indirect (e1) && is_indirect (e2)) {
|
||||||
expr_t *temp = new_temp_def_expr (t1);
|
expr_t *temp = new_temp_def_expr (t1);
|
||||||
|
|
||||||
|
@ -1750,7 +1738,9 @@ assign_expr (expr_t *e1, expr_t *e2)
|
||||||
if (e->type != ex_pointer
|
if (e->type != ex_pointer
|
||||||
|| !(e->e.pointer.val > 0 && e->e.pointer.val < 65536)) {
|
|| !(e->e.pointer.val > 0 && e->e.pointer.val < 65536)) {
|
||||||
e2 = e;
|
e2 = e;
|
||||||
op = PAS;
|
if (e2->type == ex_expr && e2->e.expr.op == '&'
|
||||||
|
&& e2->e.expr.type->type == ev_pointer)
|
||||||
|
e2->e.expr.op = '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue