Add a "void return" instruction.

I got fed up with always having to explicty return something.
This commit is contained in:
Bill Currie 2011-01-13 00:29:56 +09:00
parent 9ce9b70484
commit 3c9991364b
7 changed files with 23 additions and 7 deletions

View file

@ -290,6 +290,8 @@ typedef enum {
OP_RCALL6, OP_RCALL6,
OP_RCALL7, OP_RCALL7,
OP_RCALL8, OP_RCALL8,
OP_RETURN_V,
} pr_opcode_e; } pr_opcode_e;
typedef struct opcode_s { typedef struct opcode_s {
@ -358,7 +360,7 @@ typedef struct pr_va_list_s {
|(((0x##b) & 0xfff) << 12) \ |(((0x##b) & 0xfff) << 12) \
|(((0x##c) & 0xfff) << 0) ) |(((0x##c) & 0xfff) << 0) )
#define PROG_ID_VERSION 6 #define PROG_ID_VERSION 6
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,006) #define PROG_VERSION PROG_VERSION_ENCODE(0,fff,007)
typedef struct dprograms_s { typedef struct dprograms_s {
pr_uint_t version; pr_uint_t version;

View file

@ -923,6 +923,8 @@ op_call:
else if (&R_INT (pr) != &OPA.integer_var) else if (&R_INT (pr) != &OPA.integer_var)
memcpy (&R_INT (pr), &OPA, memcpy (&R_INT (pr), &OPA,
pr->pr_param_size * sizeof (OPA)); pr->pr_param_size * sizeof (OPA));
// fallthrough
case OP_RETURN_V:
pr->pr_xfunction->profile += profile - startprofile; pr->pr_xfunction->profile += profile - startprofile;
startprofile = profile; startprofile = profile;
PR_LeaveFunction (pr); PR_LeaveFunction (pr);

View file

@ -655,6 +655,12 @@ VISIBLE opcode_t pr_opcodes[] = {
"%Ra", "%Ra",
}, },
{"<RETURN_V>", "return", OP_RETURN_V, false,
ev_invalid, ev_invalid, ev_invalid,
PROG_VERSION,
"",
},
{"!", "not.f", OP_NOT_F, false, {"!", "not.f", OP_NOT_F, false,
ev_float, ev_invalid, ev_integer, ev_float, ev_invalid, ev_integer,
PROG_ID_VERSION, PROG_ID_VERSION,

View file

@ -34,6 +34,7 @@
extern struct opcode_s *op_done; extern struct opcode_s *op_done;
extern struct opcode_s *op_return; extern struct opcode_s *op_return;
extern struct opcode_s *op_return_v;
extern struct opcode_s *op_if; extern struct opcode_s *op_if;
extern struct opcode_s *op_ifnot; extern struct opcode_s *op_ifnot;
extern struct opcode_s *op_ifbe; extern struct opcode_s *op_ifbe;

View file

@ -877,7 +877,10 @@ emit_expr (expr_t *e)
def = 0; def = 0;
if (e->e.expr.e1) if (e->e.expr.e1)
def = emit_sub_expr (e->e.expr.e1, 0); def = emit_sub_expr (e->e.expr.e1, 0);
emit_statement (e, op_return, def, 0, 0); if (!def && op_return_v)
emit_statement (e, op_return_v, 0, 0, 0);
else
emit_statement (e, op_return, def, 0, 0);
break; break;
case 'g': case 'g':
emit_branch (e, op_goto, 0, e->e.expr.e1); emit_branch (e, op_goto, 0, e->e.expr.e1);

View file

@ -55,6 +55,7 @@ hashtab_t *opcode_type_table_abc;
opcode_t *op_done; opcode_t *op_done;
opcode_t *op_return; opcode_t *op_return;
opcode_t *op_return_v;
opcode_t *op_if; opcode_t *op_if;
opcode_t *op_ifnot; opcode_t *op_ifnot;
opcode_t *op_ifbe; opcode_t *op_ifbe;
@ -152,6 +153,8 @@ opcode_init (void)
op_done = op; op_done = op;
} else if (!strcmp (op->name, "<RETURN>")) { } else if (!strcmp (op->name, "<RETURN>")) {
op_return = op; op_return = op;
} else if (!strcmp (op->name, "<RETURN_V>")) {
op_return_v = op;
} else if (!strcmp (op->name, "<IF>")) { } else if (!strcmp (op->name, "<IF>")) {
op_if = op; op_if = op;
} else if (!strcmp (op->name, "<IFNOT>")) { } else if (!strcmp (op->name, "<IFNOT>")) {

View file

@ -258,13 +258,12 @@ subprogram_declaration
} }
declarations compound_statement ';' declarations compound_statement ';'
{ {
type_t *ret_type = $1->type->t.func.type;
current_scope = current_scope->parent; current_scope = current_scope->parent;
//current_storage = st_global; //current_storage = st_global;
//FIXME want a true void return // functions in pascal are always effectively void
if (ret_type) // but their type is needed for checking func := retval
append_expr ($5, return_expr (current_func, // so bypass the checks
new_ret_expr (ret_type))); append_expr ($5, new_unary_expr ('r', 0));
build_code_function (current_func, 0, $5); build_code_function (current_func, 0, $5);
current_func = 0; current_func = 0;
} }