mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +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_STORE_P,
|
||||
OP_STOREP_P,
|
||||
} pr_opcode_e;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -464,6 +464,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_STOREP_S:
|
||||
case OP_STOREP_FNC: // pointers
|
||||
case OP_STOREP_I:
|
||||
case OP_STOREP_P:
|
||||
//FIXME put bounds checking back
|
||||
ptr = pr->pr_globals + OPB.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.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.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.v", OP_STOREB_V, true, ev_vector, ev_pointer, ev_integer, PROG_VERSION},
|
||||
|
|
|
@ -166,74 +166,52 @@ emit_function_call (expr_t *e, def_t *dest)
|
|||
}
|
||||
|
||||
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;
|
||||
opcode_t *op;
|
||||
expr_t *e1 = e->e.expr.e1;
|
||||
expr_t *e2 = e->e.expr.e2;
|
||||
const char *operator = get_op_string (oper);
|
||||
|
||||
if (e1->type == ex_temp && e1->e.temp.users < 2) {
|
||||
e1->e.temp.users--;
|
||||
return 0;
|
||||
}
|
||||
if (e1->type == ex_expr && e1->e.expr.op == '.'
|
||||
&& 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 {
|
||||
if (oper == '=') {
|
||||
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;
|
||||
if (def_a->constant) {
|
||||
if (options.code.cow) {
|
||||
int size = pr_type_size[def_a->type->type];
|
||||
int ofs = PR_NewLocation (def_a->type);
|
||||
|
||||
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);
|
||||
memcpy (pr_globals + ofs, pr_globals + def_a->ofs, size);
|
||||
def_a->ofs = ofs;
|
||||
def_a->constant = 0;
|
||||
if (options.warnings.cow)
|
||||
warning (e1, "assignment to constant %s (Moooooooo!)",
|
||||
def_a->name);
|
||||
} 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 (options.code.cow) {
|
||||
int size = pr_type_size[def_a->type->type];
|
||||
int ofs = PR_NewLocation (def_a->type);
|
||||
|
||||
memcpy (pr_globals + ofs, pr_globals + def_a->ofs, size);
|
||||
def_a->ofs = ofs;
|
||||
def_a->constant = 0;
|
||||
if (options.warnings.cow)
|
||||
warning (e1, "assignment to constant %s (Moooooooo!)",
|
||||
def_a->name);
|
||||
} else {
|
||||
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);
|
||||
} else {
|
||||
def_b = emit_sub_expr (e2, def_a);
|
||||
}
|
||||
if (def_b != def_a) {
|
||||
op = PR_Opcode_Find (operator, def_b, def_a, &def_void);
|
||||
emit_statement (e->line, op, def_b, def_a, 0);
|
||||
error (e1, "assignment to constant %s", def_a->name);
|
||||
}
|
||||
}
|
||||
def_b = emit_sub_expr (e2, def_a);
|
||||
if (def_b != def_a) {
|
||||
op = PR_Opcode_Find (operator, def_b, def_a, &def_void);
|
||||
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)
|
||||
return def_a;
|
||||
|
@ -289,8 +267,8 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
d = emit_function_call (e, dest);
|
||||
break;
|
||||
}
|
||||
if (e->e.expr.op == '=') {
|
||||
d = emit_assign_expr ("=", e);
|
||||
if (e->e.expr.op == '=' || e->e.expr.op == PAS) {
|
||||
d = emit_assign_expr (e->e.expr.op, e);
|
||||
break;
|
||||
}
|
||||
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->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);
|
||||
if (!d->name)
|
||||
d->type = e->e.expr.type;
|
||||
|
@ -454,7 +435,7 @@ emit_expr (expr_t *e)
|
|||
switch (e->e.expr.op) {
|
||||
case PAS:
|
||||
case '=':
|
||||
emit_assign_expr (get_op_string (e->e.expr.op), e);
|
||||
emit_assign_expr (e->e.expr.op, e);
|
||||
break;
|
||||
case 'n':
|
||||
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 '.':
|
||||
if (extract_type (e) != ev_pointer)
|
||||
return error (e, "invalid type for unary .");
|
||||
if (e->type == ex_expr && e->e.expr.op == '&'
|
||||
&& (extract_type (e->e.expr.e1) == ev_entity
|
||||
|| extract_type (e->e.expr.e1) == ev_pointer)) {
|
||||
e->e.expr.op = '.';
|
||||
e->e.expr.type = e->e.expr.type->aux_type;
|
||||
} else {
|
||||
//if (e->type == ex_expr && e->e.expr.op == '&'
|
||||
// && (extract_type (e->e.expr.e1) == ev_entity
|
||||
// || extract_type (e->e.expr.e1) == ev_pointer)) {
|
||||
// e->e.expr.op = '.';
|
||||
// e->e.expr.type = e->e.expr.type->aux_type;
|
||||
//} else {
|
||||
e = new_unary_expr ('.', e);
|
||||
e->e.expr.type = get_type (e->e.expr.e1)->aux_type;
|
||||
}
|
||||
//}
|
||||
return e;
|
||||
}
|
||||
error (e, "internal error");
|
||||
|
@ -1606,7 +1606,6 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
if (!t)
|
||||
t = get_type (e1);
|
||||
|
||||
// print_expr (e1);puts("");
|
||||
switch (e1->type) {
|
||||
case ex_def:
|
||||
type = e1->e.def->type;
|
||||
|
@ -1629,9 +1628,6 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
e = e1;
|
||||
e->e.expr.op = '&';
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
e->e.pointer.val += e2->e.short_val;
|
||||
} else {
|
||||
// print_expr (e); puts("");
|
||||
// print_expr (e2); puts("");
|
||||
if (e2->type != ex_short || e2->e.short_val) {
|
||||
// print_expr (e2);puts("");
|
||||
e = new_binary_expr ('&', e, e2);
|
||||
}
|
||||
if (e->type == ex_expr || e->type == ex_uexpr)
|
||||
e->e.expr.type = pointer_type (t);
|
||||
}
|
||||
}
|
||||
// print_expr (e);puts("");
|
||||
// puts("");
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -1718,9 +1709,6 @@ assign_expr (expr_t *e1, expr_t *e2)
|
|||
return type_mismatch (e1, e2, op);
|
||||
else
|
||||
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)) {
|
||||
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
|
||||
|| !(e->e.pointer.val > 0 && e->e.pointer.val < 65536)) {
|
||||
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