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:
Bill Currie 2001-12-12 20:35:58 +00:00
parent b56d7f3248
commit 8ddce20949
5 changed files with 50 additions and 76 deletions

View file

@ -242,6 +242,7 @@ typedef enum {
OP_LOAD_P,
OP_STORE_P,
OP_STOREP_P,
} pr_opcode_e;
typedef struct

View file

@ -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;

View file

@ -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},

View file

@ -166,43 +166,20 @@ 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;
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 (options.code.cow) {
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);
}
}
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);
}
} 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);

View file

@ -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 = '.';
}
}
}