cvsuser 03/11/16 16:48:04
Modified: imcc instructions.h instructions.c cfg.c sub.c pcc.c
symreg.c
Log:
Add high level subroutine call syntax to IMCC. Defaults to prototyped
for now until calling conventions are correctly implemented.
Supports no-return, single return, or multiple returns. Variable list
for multiple returns must be inside parens.
Following syntax is supported:
_foo()
_foo(a,b)
i = _foo(a)
(i,j) = _foo(a,b)
Flattening is not yet implemented for this syntax.
This construct will automatically create all of the .pcc_*
code needed for the call and results.
Revision Changes Path
1.42 +1 -0 parrot/imcc/instructions.h
Index: instructions.h
===================================================================
RCS file: /cvs/public/parrot/imcc/instructions.h,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -w -r1.41 -r1.42
--- instructions.h 13 Nov 2003 06:46:03 -0000 1.41
+++ instructions.h 17 Nov 2003 00:48:03 -0000 1.42
@@ -97,6 +97,7 @@
Instruction *delete_ins(struct _IMC_Unit *, Instruction *ins, int needs_freeing);
void insert_ins(struct _IMC_Unit *, Instruction *ins, Instruction * tmp);
+void prepend_ins(struct _IMC_Unit *, Instruction *ins, Instruction * tmp);
Instruction *move_ins(struct _IMC_Unit *, Instruction *cur, Instruction *to);
void subst_ins(struct _IMC_Unit *, Instruction *ins, Instruction * tmp, int);
1.50 +26 -0 parrot/imcc/instructions.c
Index: instructions.c
===================================================================
RCS file: /cvs/public/parrot/imcc/instructions.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -w -r1.49 -r1.50
--- instructions.c 13 Nov 2003 07:05:00 -0000 1.49
+++ instructions.c 17 Nov 2003 00:48:03 -0000 1.50
@@ -271,6 +271,32 @@
}
/*
+ * insert tmp before ins
+ */
+void
+prepend_ins(IMC_Unit *unit, Instruction *ins, Instruction * tmp)
+{
+ Instruction *next, *prev;
+ if (!ins) {
+ next = unit->instructions;
+ unit->instructions = tmp;
+ tmp->next = next;
+ next->prev = tmp;
+ tmp->line = next->line;
+ }
+ else {
+ prev = ins->prev;
+ ins->prev = tmp;
+ tmp->next = ins;
+ tmp->prev = prev;
+ if (prev)
+ prev->next = tmp;
+ if (!tmp->line)
+ tmp->line = ins->line;
+ }
+}
+
+/*
* subst tmp for ins
*/
1.54 +2 -0 parrot/imcc/cfg.c
Index: cfg.c
===================================================================
RCS file: /cvs/public/parrot/imcc/cfg.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -w -r1.53 -r1.54
--- cfg.c 16 Nov 2003 04:31:40 -0000 1.53
+++ cfg.c 17 Nov 2003 00:48:03 -0000 1.54
@@ -113,6 +113,7 @@
add_instruct_writes(ins, p0);
add_instruct_writes(ins, p1);
}
+
if (ins->opnum == -1 && (ins->type & ITPCCSUB)) {
if (first) {
/* XXX FIXME: Now the way to check for a sub is unit->type */
@@ -131,6 +132,7 @@
/* set the labels address (ins) */
ins->r[0]->first_ins = ins;
}
+
/* a LABEL starts a new basic block, but not, if we already have
* a new one (last was a branch)
*/
1.2 +3 -3 parrot/imcc/sub.c
Index: sub.c
===================================================================
RCS file: /cvs/public/parrot/imcc/sub.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- sub.c 16 Nov 2003 04:28:10 -0000 1.1
+++ sub.c 17 Nov 2003 00:48:03 -0000 1.2
@@ -44,7 +44,7 @@
{
/* IMC_FASTSUB */
#if IMC_TRACE
- PIO_eprintf("expand_sub\n");
+ PIO_eprintf(NULL, "expand_sub\n");
#endif
/* For expand sub, we check the unit->type only, since the
* pragma might be overridden.
@@ -67,7 +67,7 @@
expand_sub_ret(Parrot_Interp interp, IMC_Unit * unit, Instruction *ins)
{
#if IMC_TRACE
- PIO_eprintf("expand_sub_ret\n");
+ PIO_eprintf(NULL, "expand_sub_ret\n");
#endif
/* IMC_FASTSUB */
if(pragmas.fastcall) {
@@ -87,7 +87,7 @@
expand_sub_call(Parrot_Interp interp, IMC_Unit * unit, Instruction *ins)
{
#if IMC_TRACE
- PIO_eprintf("expand_sub_call\n");
+ PIO_eprintf(NULL, "expand_sub_call\n");
#endif
/* IMC_FASTSUB */
if(pragmas.fastcall) {
1.33 +48 -26 parrot/imcc/pcc.c
Index: pcc.c
===================================================================
RCS file: /cvs/public/parrot/imcc/pcc.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -w -r1.32 -r1.33
--- pcc.c 16 Nov 2003 04:31:40 -0000 1.32
+++ pcc.c 17 Nov 2003 00:48:03 -0000 1.33
@@ -222,7 +222,7 @@
char buf[128];
#if IMC_TRACE
- PIO_eprintf("expand_pcc_sub\n");
+ PIO_eprintf(NULL, "expand_pcc_sub\n");
#endif
sub = ins->r[1];
@@ -366,7 +366,7 @@
int n_p3;
#if IMC_TRACE
- PIO_eprintf("expand_pcc_sub_ret\n");
+ PIO_eprintf(NULL, "expand_pcc_sub_ret\n");
#endif
arg_count = ins->type & ITPCCYIELD ? 0 : 1;
@@ -725,7 +725,7 @@
* This is the nuts and bolts of Perl6/Parrot routine call style
*/
void
-expand_pcc_sub_call(Parrot_Interp interpreter, IMC_Unit * unit, Instruction *ins)
+expand_pcc_sub_call(Parrot_Interp interp, IMC_Unit * unit, Instruction *ins)
{
SymReg *arg, *sub, *reg, *arg_reg, *regs[IMCC_MAX_REGS];
int next[4], i, j, n;
@@ -739,12 +739,12 @@
int flatten;
#if IMC_TRACE
- PIO_eprintf("expand_pcc_sub_call\n");
+ PIO_eprintf(NULL, "expand_pcc_sub_call\n");
#endif
- tail_call = check_tail_call(interpreter, unit, ins);
+ tail_call = check_tail_call(interp, unit, ins);
if (tail_call)
- debug(interpreter, DEBUG_OPT1, "found tail call %I \n", ins);
+ debug(interp, DEBUG_OPT1, "found tail call %I \n", ins);
for (i = 0; i < 4; i++)
next[i] = 5;
call_ins = ins;
@@ -752,9 +752,31 @@
p3 = NULL;
n_p3 = 0;
flatten = 0;
+
+ /*
+ * See if we need to create a temporary sub object
+ */
+ if(ins->type & ITCALL) {
+#if IMC_TRACE
+ fprintf(stderr, "generating sub object [sub->name = %s]\n",
sub->pcc_sub->sub->name);
+#endif
+ /* sub->pcc_sub->sub is an actual subroutine name, not a variable. */
+ reg = mk_temp_reg('P');
+ tmp = iNEWSUB(interp, unit, reg, NEWSUB, sub->pcc_sub->sub, NULL, 0);
+ add_pcc_sub(sub, reg);
+ ins->type &= ~ITCALL;
+ prepend_ins(unit, ins, tmp);
+
+ expand_pcc_sub_call(interp, unit, ins);
+ return;
+ }
+
/*
* insert arguments
*/
+#if IMC_TRACE
+ PIO_eprintf(NULL, "expand_pcc_sub_call: nargs = %d\n", sub->pcc_sub->nargs);
+#endif
n = sub->pcc_sub->nargs;
for (i = 0; i < n; i++) {
/*
@@ -781,7 +803,7 @@
reg = mk_pasm_reg(str_dup(buf));
regs[0] = reg;
regs[1] = arg_reg;
- ins = insINS(interpreter, unit, ins, "set", regs, 2);
+ ins = insINS(interp, unit, ins, "set", regs, 2);
/* remember reg for life analysis */
sub->pcc_sub->args[i]->used = reg;
@@ -811,19 +833,19 @@
overflow:
if (!p3) {
p3 = mk_pasm_reg(str_dup("P3"));
- tmp = iNEW(interpreter, unit, p3, str_dup("SArray"), NULL, 0);
+ tmp = iNEW(interp, unit, p3, str_dup("SArray"), NULL, 0);
insert_ins(unit, ins, tmp);
ins = tmp;
sprintf(buf, "%d", n);
regs[0] = p3;
regs[1] = mk_const(str_dup(buf), 'I');
- ins = insINS(interpreter, unit, ins, "set", regs, 2);
+ ins = insINS(interp, unit, ins, "set", regs, 2);
}
if (flatten || (arg_reg->type & VT_FLATTEN))
goto flatten;
regs[0] = p3;
regs[1] = arg;
- ins = insINS(interpreter, unit, ins, "push", regs, 2);
+ ins = insINS(interp, unit, ins, "push", regs, 2);
n_p3++;
}
continue;
@@ -831,7 +853,7 @@
/* if we had a flattening arg, we must continue emitting
* code to do all at runtime
*/
- ins = pcc_emit_flatten(interpreter, unit, ins, arg_reg, i, &flatten);
+ ins = pcc_emit_flatten(interp, unit, ins, arg_reg, i, &flatten);
} /* for i */
/*
@@ -839,7 +861,7 @@
* insert a jump
*/
if (tail_call) {
- insert_tail_call(interpreter, unit, ins, sub);
+ insert_tail_call(interp, unit, ins, sub);
return;
}
@@ -854,7 +876,7 @@
regs[0] = reg;
regs[1] = arg;
arg->reg->want_regno = 0;
- ins = insINS(interpreter, unit, ins, "set", regs, 2);
+ ins = insINS(interp, unit, ins, "set", regs, 2);
}
}
else {
@@ -872,7 +894,7 @@
regs[0] = reg;
regs[1] = arg;
arg->reg->want_regno = 1;
- ins = insINS(interpreter, unit, ins, "set", regs, 2);
+ ins = insINS(interp, unit, ins, "set", regs, 2);
}
}
else {
@@ -883,24 +905,24 @@
else if (!sub->pcc_sub->nci)
need_cc = 1;
/* set prototyped: I0 */
- ins = set_I_const(interpreter, unit, ins, 0, sub->pcc_sub->prototyped);
+ ins = set_I_const(interp, unit, ins, 0, sub->pcc_sub->prototyped);
/* set items in P3: I1 */
- ins = set_I_const(interpreter, unit, ins, 1, n_p3);
+ ins = set_I_const(interp, unit, ins, 1, n_p3);
/* set items in PRegs: I2 */
if (flatten) {
regs[0] = mk_pasm_reg(str_dup("I2"));;
regs[1] = mk_const(str_dup("5"), 'I');
- ins = insINS(interpreter, unit, ins, "sub", regs, 2);
+ ins = insINS(interp, unit, ins, "sub", regs, 2);
}
else
- ins = set_I_const(interpreter, unit, ins, 2, next[2] - 5);
+ ins = set_I_const(interp, unit, ins, 2, next[2] - 5);
/* return type 0=void, or -n-1: I3 */
- ins = set_I_const(interpreter, unit, ins, 3,
+ ins = set_I_const(interp, unit, ins, 3,
sub->pcc_sub->nret ? -1 - sub->pcc_sub->nret : 0);
#if 0
/* TODO method calls */
/* meth hash value: I4 */
- ins = set_I_const(interpreter, unit, ins, 4, 0);
+ ins = set_I_const(interp, unit, ins, 4, 0);
/* meth name: S0 */
/* object: P2 */
#endif
@@ -909,12 +931,12 @@
*/
if (!sub->pcc_sub->nci)
if (!need_cc)
- ins = insINS(interpreter, unit, ins, "updatecc", regs, 0);
+ ins = insINS(interp, unit, ins, "updatecc", regs, 0);
/*
* emit a savetop for now
*/
- ins = insINS(interpreter, unit, ins, "savetop", regs, 0);
- ins = insINS(interpreter, unit, ins, need_cc ? "invokecc" : "invoke", regs, 0);
+ ins = insINS(interp, unit, ins, "savetop", regs, 0);
+ ins = insINS(interp, unit, ins, need_cc ? "invokecc" : "invoke", regs, 0);
ins->type |= ITPCCSUB;
/*
* move the pcc_sub structure to the invoke
@@ -929,7 +951,7 @@
*/
if (ins->next->type == ITLABEL && sub->pcc_sub->label)
ins = ins->next;
- ins = insINS(interpreter, unit, ins, "restoretop", regs, 0);
+ ins = insINS(interp, unit, ins, "restoretop", regs, 0);
/*
* handle return results
* TODO: overflow
@@ -952,7 +974,7 @@
reg = mk_pasm_reg(str_dup(buf));
regs[0] = arg;
regs[1] = reg;
- ins = insINS(interpreter, unit, ins, "set", regs, 2);
+ ins = insINS(interp, unit, ins, "set", regs, 2);
sub->pcc_sub->ret[i]->used = reg;
break;
}
@@ -963,7 +985,7 @@
p3 = mk_pasm_reg(str_dup("P3"));
regs[0] = arg;
regs[1] = p3;
- ins = insINS(interpreter, unit, ins, "shift", regs, 2);
+ ins = insINS(interp, unit, ins, "shift", regs, 2);
}
}
}
1.40 +1 -0 parrot/imcc/symreg.c
Index: symreg.c
===================================================================
RCS file: /cvs/public/parrot/imcc/symreg.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -w -r1.39 -r1.40
--- symreg.c 13 Nov 2003 07:22:08 -0000 1.39
+++ symreg.c 17 Nov 2003 00:48:03 -0000 1.40
@@ -154,6 +154,7 @@
r->pcc_sub->sub->reg = arg;
r->pcc_sub->sub->type = VT_REGP;
}
+
void
add_pcc_cc(SymReg *r, SymReg * arg)
{