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_LOAD_P,
OP_STORE_P, OP_STORE_P,
OP_STOREP_P,
} pr_opcode_e; } pr_opcode_e;
typedef struct typedef struct

View file

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

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

View file

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

View file

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