commit - 4efc4256d0461a3fbc9abdb3443dc7aa73e763c3
commit + 0d35c07dfc7e6b341aadc64a253738b6285b9e6a
blob - 8566d7c50703dc2618f31bc44f94e28fa8129567
blob + fbd52308aca953b521e52120d240c43707f30f48
--- cc/irc/irc.c
+++ cc/irc/irc.c
long i;
double f;
struct {
- int num;
- int off;
+ struct regimm num;
+ int off; // only valid if ri.is_imm
} alloca;
struct {
int l;
error ("the result of alloca must be stored in a far or stack pointer");
e->type = EX_ALLOCA;
- expect (TK_INT);
- e->alloca.num = lval.i;
- stalloc (fn, sizeof_dt (dt->inner) * e->alloca.num);
- e->alloca.off = fn->stoff;
+ regimm (&e->alloca.num, &default_dt);
+ if (e->alloca.num.is_imm) {
+ stalloc (fn, sizeof_dt (dt->inner) * e->alloca.num.imm);
+ e->alloca.off = fn->stoff;
+ }
expect (';');
} else if (strcmp (lval.s, "ptradd") == 0) {
e->type = EX_PTRADD;
printf ("$%d", e->reg);
break;
case EX_ALLOCA:
- printf ("alloca %d", e->alloca.num);
+ printf ("alloca ");
+ print_ri (&e->alloca.num);
break;
case EX_ADD:
printf ("add $%d, ", e->bin.l);
puts ("\tmov dx, ss");
// fallthrough
case DT_SPTR:
- printf ("\tlea ax, [bp + %d]\n", e->alloca.off);
+ if (e->alloca.num.is_imm) {
+ printf ("\tlea ax, [bp + %d]\n", e->alloca.off);
+ } else {
+ loadw (NULL, AX, &fn->regs[e->alloca.num.reg]);
+ cmul ("ax", sizeof_dt (dt->inner));
+ puts ("\tsub sp, ax");
+ puts ("\tmov ax, sp");
+ }
break;
default:
abort ();
blob - 1d6a10ae6bf33408ac50b80ade2bedfd35342862
blob + 08dc0947bade90c0785e263d4809546f818db9ad
--- cc/irc/test.ir
+++ cc/irc/test.ir
nop;
ret 0;
}
+
+fn alloca_reg ($0: word): word {
+ let $1: ^word = alloca $0;
+ let $2: word = read $1, 5;
+ ret $2;
+}