summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2021-10-18 21:04:10 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2021-10-22 23:53:25 +0200
commitfcdef10dae54d7124aca9ccbefe53baa8e67267d (patch)
tree1215b60f1f3a31d38ee37228dd37bcc4a6a61f99
parent9858a12730717d9c5e5deec4264d7041d75fc947 (diff)
downloadroux-fcdef10dae54d7124aca9ccbefe53baa8e67267d.tar.gz
make variadic args explicit
Some abis, like the riscv one, treat
arguments differently depending on
whether they are variadic or not.
To prepare for the upcomming riscv
target, we change the variadic call
syntax and give meaning to the
location of the '...' marker.

  # new syntax
  %ret =w call $f(w %regular, ..., w %variadic)

By nature of their abis, the change
is backwards compatible for existing
targets.
-rw-r--r--all.h3
-rw-r--r--amd64/sysv.c34
-rw-r--r--arm64/abi.c17
-rw-r--r--doc/il.txt6
-rw-r--r--live.c2
-rw-r--r--load.c2
-rw-r--r--ops.h2
-rw-r--r--parse.c48
-rw-r--r--test/_slow.qbe10
-rw-r--r--test/abi5.ssa18
-rw-r--r--test/abi6.ssa4
-rw-r--r--test/echo.ssa2
-rw-r--r--test/vararg2.ssa28
13 files changed, 101 insertions, 75 deletions
diff --git a/all.h b/all.h
index 4b9eb0e..37980d3 100644
--- a/all.h
+++ b/all.h
@@ -171,12 +171,11 @@ enum {
 };
 
 #define INRANGE(x, l, u) ((unsigned)(x) - l <= u - l) /* linear in x */
-#define iscall(o) INRANGE(o, Ocall, Ovacall)
 #define isstore(o) INRANGE(o, Ostoreb, Ostored)
 #define isload(o) INRANGE(o, Oloadsb, Oload)
 #define isext(o) INRANGE(o, Oextsb, Oextuw)
 #define ispar(o) INRANGE(o, Opar, Opare)
-#define isarg(o) INRANGE(o, Oarg, Oarge)
+#define isarg(o) INRANGE(o, Oarg, Oargv)
 #define isret(j) INRANGE(j, Jret0, Jretc)
 
 enum Class {
diff --git a/amd64/sysv.c b/amd64/sysv.c
index 842f645..2e3e4a8 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -153,7 +153,7 @@ selret(Blk *b, Fn *fn)
 static int
 argsclass(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret, Ref *env)
 {
-	int nint, ni, nsse, ns, n, *pn;
+	int varc, envc, nint, ni, nsse, ns, n, *pn;
 	AClass *a;
 	Ins *i;
 
@@ -162,6 +162,8 @@ argsclass(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret, Ref *env)
 	else
 		nint = 6;
 	nsse = 8;
+	varc = 0;
+	envc = 0;
 	for (i=i0, a=ac; i<i1; i++, a++)
 		switch (i->op - op + Oarg) {
 		case Oarg:
@@ -196,14 +198,23 @@ argsclass(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret, Ref *env)
 				a->inmem = 1;
 			break;
 		case Oarge:
+			envc = 1;
 			if (op == Opar)
 				*env = i->to;
 			else
 				*env = i->arg[0];
 			break;
+		case Oargv:
+			varc = 1;
+			break;
+		default:
+			die("unreachable");
 		}
 
-	return (!req(R, *env) << 12) | ((6-nint) << 4) | ((8-nsse) << 8);
+	if (varc && envc)
+		err("sysv abi does not support variadic env calls");
+
+	return ((varc|envc) << 12) | ((6-nint) << 4) | ((8-nsse) << 8);
 }
 
 int amd64_sysv_rsave[] = {
@@ -290,7 +301,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 {
 	Ins *i;
 	AClass *ac, *a, aret;
-	int ca, ni, ns, al, varc, envc;
+	int ca, ni, ns, al;
 	uint stk, off;
 	Ref r, r1, r2, reg[2], env;
 	RAlloc *ra;
@@ -358,22 +369,20 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 			ca += 1 << 2;
 		}
 	}
-	envc = !req(R, env);
-	varc = i1->op == Ovacall;
-	if (varc && envc)
-		err("sysv abi does not support variadic env calls");
-	ca |= varc << 12; /* envc set in argsclass() */
+
 	emit(Ocall, i1->cls, R, i1->arg[0], CALL(ca));
-	if (envc)
+
+	if (!req(R, env))
 		emit(Ocopy, Kl, TMP(RAX), env, R);
-	if (varc)
+	else if ((ca >> 12) & 1) /* vararg call */
 		emit(Ocopy, Kw, TMP(RAX), getcon((ca >> 8) & 15, fn), R);
 
 	ni = ns = 0;
 	if (ra && aret.inmem)
 		emit(Ocopy, Kl, rarg(Kl, &ni, &ns), ra->i.to, R); /* pass hidden argument */
+
 	for (i=i0, a=ac; i<i1; i++, a++) {
-		if (a->inmem || i->op == Oarge)
+		if (i->op >= Oarge || a->inmem)
 			continue;
 		r1 = rarg(a->cls[0], &ni, &ns);
 		if (i->op == Oargc) {
@@ -393,7 +402,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 
 	r = newtmp("abi", Kl, fn);
 	for (i=i0, a=ac, off=0; i<i1; i++, a++) {
-		if (!a->inmem)
+		if (i->op >= Oarge || !a->inmem)
 			continue;
 		if (i->op == Oargc) {
 			if (a->align == 4)
@@ -676,7 +685,6 @@ amd64_sysv_abi(Fn *fn)
 				emiti(*i);
 				break;
 			case Ocall:
-			case Ovacall:
 				for (i0=i; i0>b->ins; i0--)
 					if (!isarg((i0-1)->op))
 						break;
diff --git a/arm64/abi.c b/arm64/abi.c
index 5fe9553..d38dcf5 100644
--- a/arm64/abi.c
+++ b/arm64/abi.c
@@ -255,6 +255,10 @@ argsclass(Ins *i0, Ins *i1, Class *carg, Ref *env)
 		case Oarge:
 			*env = i->arg[0];
 			break;
+		case Oargv:
+			break;
+		default:
+			die("unreachable");
 		}
 
 	return ((gp-gpreg) << 5) | ((fp-fpreg) << 9);
@@ -371,10 +375,11 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 		}
 	}
 
+	emit(Ocall, 0, R, i1->arg[0], CALL(cty));
+
 	envc = !req(R, env);
 	if (envc)
 		die("todo (arm abi): env calls");
-	emit(Ocall, 0, R, i1->arg[0], CALL(cty));
 
 	if (cty & (1 << 13))
 		/* struct return argument */
@@ -383,9 +388,9 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 	for (i=i0, c=ca; i<i1; i++, c++) {
 		if ((c->class & Cstk) != 0)
 			continue;
-		if (i->op != Oargc)
+		if (i->op == Oarg)
 			emit(Ocopy, *c->cls, TMP(*c->reg), i->arg[0], R);
-		else
+		if (i->op == Oargc)
 			ldregs(c->reg, c->cls, c->nreg, i->arg[1], fn);
 	}
 
@@ -393,11 +398,12 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 	for (i=i0, c=ca; i<i1; i++, c++) {
 		if ((c->class & Cstk) == 0)
 			continue;
-		if (i->op != Oargc) {
+		if (i->op == Oarg) {
 			r = newtmp("abi", Kl, fn);
 			emit(Ostorel, 0, R, i->arg[0], r);
 			emit(Oadd, Kl, r, TMP(SP), getcon(off, fn));
-		} else
+		}
+		if (i->op == Oargc)
 			blit(TMP(SP), off, i->arg[1], c->size, fn);
 		off += c->size;
 	}
@@ -675,7 +681,6 @@ arm64_abi(Fn *fn)
 				emiti(*i);
 				break;
 			case Ocall:
-			case Ovacall:
 				for (i0=i; i0>b->ins; i0--)
 					if (!isarg((i0-1)->op))
 						break;
diff --git a/doc/il.txt b/doc/il.txt
index d1ed755..87a4d9f 100644
--- a/doc/il.txt
+++ b/doc/il.txt
@@ -751,7 +751,7 @@ single-precision floating point number `%f` into `%rs`.
     ARG :=
         ABITY VAL  # Regular argument
       | 'env' VAL  # Environment argument (first)
-      | '...'      # Variadic marker (last)
+      | '...'      # Variadic marker
 
     ABITY := BASETY | :IDENT
 
@@ -778,8 +778,8 @@ integer.  If the called function does not expect an environment
 parameter, it will be safely discarded.  See the <@ Functions >
 section for more information about environment parameters.
 
-When the called function is variadic, the last argument
-must be `...`.
+When the called function is variadic, there must be a `...`
+marker separating the named and variadic arguments.
 
 ~ Variadic
 ~~~~~~~~~~
diff --git a/live.c b/live.c
index c22e063..4198995 100644
--- a/live.c
+++ b/live.c
@@ -82,7 +82,7 @@ Again:
 		for (k=0; k<2; k++)
 			b->nlive[k] = nlv[k];
 		for (i=&b->ins[b->nins]; i!=b->ins;) {
-			if (iscall((--i)->op) && rtype(i->arg[1]) == RCall) {
+			if ((--i)->op == Ocall && rtype(i->arg[1]) == RCall) {
 				b->in->t[0] &= ~T.retregs(i->arg[1], m);
 				for (k=0; k<2; k++) {
 					nlv[k] -= m[k];
diff --git a/load.c b/load.c
index f3a695b..5d61a6c 100644
--- a/load.c
+++ b/load.c
@@ -234,7 +234,7 @@ def(Slice sl, bits msk, Blk *b, Ins *i, Loc *il)
 	while (i > b->ins) {
 		--i;
 		if (killsl(i->to, sl)
-		|| (iscall(i->op) && escapes(sl.ref, curf)))
+		|| (i->op == Ocall && escapes(sl.ref, curf)))
 			goto Load;
 		ld = isload(i->op);
 		if (ld) {
diff --git a/ops.h b/ops.h
index 114310c..535be71 100644
--- a/ops.h
+++ b/ops.h
@@ -137,8 +137,8 @@ O(pare,    T(e,x,e,e, e,x,e,e), 0) X(0, 0, 0)
 O(arg,     T(w,l,s,d, x,x,x,x), 0) X(0, 0, 0)
 O(argc,    T(e,x,e,e, e,l,e,e), 0) X(0, 0, 0)
 O(arge,    T(e,l,e,e, e,x,e,e), 0) X(0, 0, 0)
+O(argv,    T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0)
 O(call,    T(m,m,m,m, x,x,x,x), 0) X(0, 0, 0)
-O(vacall,  T(m,m,m,m, x,x,x,x), 0) X(0, 0, 0)
 
 /* Flags Setting */
 O(flagieq,  T(x,x,e,e, x,x,e,e), 0) X(0, 0, 1)
diff --git a/parse.c b/parse.c
index da88f58..104ca1d 100644
--- a/parse.c
+++ b/parse.c
@@ -450,25 +450,44 @@ parsecls(int *tyn)
 static int
 parserefl(int arg)
 {
-	int k, ty, env, hasenv;
+	int k, ty, env, hasenv, vararg;
 	Ref r;
 
 	hasenv = 0;
+	vararg = 0;
 	expect(Tlparen);
-	while (peek() != Trparen && peek() != Tdots) {
+	while (peek() != Trparen) {
 		if (curi - insb >= NIns)
 			err("too many instructions (1)");
-		env = peek() == Tenv;
-		if (env) {
+		if (!arg && vararg)
+			err("no parameters allowed after '...'");
+		switch (peek()) {
+		case Tdots:
+			if (vararg)
+				err("only one '...' allowed");
+			vararg = 1;
+			if (arg) {
+				*curi = (Ins){.op = Oargv};
+				curi++;
+			}
+			next();
+			goto Next;
+		case Tenv:
+			if (hasenv)
+				err("only one environment allowed");
+			hasenv = 1;
+			env = 1;
 			next();
 			k = Kl;
-		} else
+			break;
+		default:
+			env = 0;
 			k = parsecls(&ty);
+			break;
+		}
 		r = parseref();
 		if (req(r, R))
 			err("invalid argument");
-		if (hasenv && env)
-			err("only one environment allowed");
 		if (!arg && rtype(r) != RTmp)
 			err("invalid function parameter");
 		if (k == 4)
@@ -487,16 +506,13 @@ parserefl(int arg)
 			else
 				*curi = (Ins){Opar, k, r, {R}};
 		curi++;
-		hasenv |= env;
+	Next:
 		if (peek() == Trparen)
 			break;
 		expect(Tcomma);
 	}
-	if (next() == Tdots) {
-		expect(Trparen);
-		return 1;
-	}
-	return 0;
+	expect(Trparen);
+	return vararg;
 }
 
 static Blk *
@@ -621,10 +637,8 @@ DoOp:
 	}
 	if (op == Tcall) {
 		arg[0] = parseref();
-		if (parserefl(1))
-			op = Ovacall;
-		else
-			op = Ocall;
+		parserefl(1);
+		op = Ocall;
 		expect(Tnl);
 		if (k == 4) {
 			k = Kl;
diff --git a/test/_slow.qbe b/test/_slow.qbe
index 2d107ae..a411e41 100644
--- a/test/_slow.qbe
+++ b/test/_slow.qbe
@@ -3408,7 +3408,7 @@ function $transparent_crc(l %.1, l %.3, w %.5) {
 	%.9 =l copy $.Lstring.93
 	%.10 =l loadl %.4
 	%.11 =l loadl %.2
-	%.12 =w call $printf(l %.9, l %.10, l %.11, ...)
+	%.12 =w call $printf(l %.9, ..., l %.10, l %.11)
 @if_false.679
 	%.13 =l loadl $crc32_context
 	%.14 =l loadl %.2
@@ -3461,7 +3461,7 @@ function $transparent_crc_bytes(l %.1, w %.3, l %.5, w %.7) {
 	%.28 =l loadl $crc32_context
 	%.29 =l copy 4294967295
 	%.30 =l xor %.28, %.29
-	%.31 =w call $printf(l %.26, l %.27, l %.30, ...)
+	%.31 =w call $printf(l %.26, ..., l %.27, l %.30)
 @if_false.687
 	ret
 }
@@ -3480,7 +3480,7 @@ function $platform_main_end(l %.1, w %.3) {
 @if_true.690
 	%.8 =l copy $.Lstring.97
 	%.9 =l loadl %.2
-	%.10 =w call $printf(l %.8, l %.9, ...)
+	%.10 =w call $printf(l %.8, ..., l %.9)
 @if_false.691
 	ret
 }
@@ -35219,7 +35219,7 @@ function w $main(w %.1, l %.3) {
 	%.53 =w loadsw %.5
 	%.54 =w loadsw %.6
 	%.55 =w loadsw %.7
-	%.56 =w call $printf(l %.52, w %.53, w %.54, w %.55, ...)
+	%.56 =w call $printf(l %.52, ..., w %.53, w %.54, w %.55)
 @if_false.1519
 @for_cont.1516
 	%.57 =w loadsw %.7
@@ -35338,7 +35338,7 @@ function w $main(w %.1, l %.3) {
 @if_true.1524
 	%.138 =l copy $.Lstring.129
 	%.139 =w loadsw %.5
-	%.140 =w call $printf(l %.138, w %.139, ...)
+	%.140 =w call $printf(l %.138, ..., w %.139)
 @if_false.1525
 @for_cont.1522
 	%.141 =w loadsw %.5
diff --git a/test/abi5.ssa b/test/abi5.ssa
index edfda4e..1d823b1 100644
--- a/test/abi5.ssa
+++ b/test/abi5.ssa
@@ -25,41 +25,41 @@ export
 function $test() {
 @start
 	%r1 =:st1 call $t1()
-	%i1 =w call $printf(l $fmt1, l %r1, ...)
+	%i1 =w call $printf(l $fmt1, ..., l %r1)
 
 	%r2 =:st2 call $t2()
 	%w2 =w loadw %r2
-	%i2 =w call $printf(l $fmt2, w %w2, ...)
+	%i2 =w call $printf(l $fmt2, ..., w %w2)
 
 	%r3 =:st3 call $t3()
 	%s3 =s loads %r3
 	%r34 =l add %r3, 4
 	%w3 =w loadw %r34
 	%p3 =d exts %s3
-	%i3 =w call $printf(l $fmt3, d %p3, w %w3, ...)
+	%i3 =w call $printf(l $fmt3, ..., d %p3, w %w3)
 
 	%r4 =:st4 call $t4()
 	%w4 =w loadw %r4
 	%r48 =l add 8, %r4
 	%d4 =d loadd %r48
-	%i4 =w call $printf(l $fmt4, w %w4, d %d4, ...)
+	%i4 =w call $printf(l $fmt4, ..., w %w4, d %d4)
 
 	%r5 =:st5 call $t5()
 	%s5 =s loads %r5
 	%d5 =d exts %s5
 	%r58 =l add %r5, 8
 	%l5 =l loadl %r58
-	%i5 =w call $printf(l $fmt5, d %d5, l %l5, ...)
+	%i5 =w call $printf(l $fmt5, ..., d %d5, l %l5)
 
 	%r6 =:st6 call $t6()
-	%i6 =w call $printf(l $fmt6, l %r6, ...)
+	%i6 =w call $printf(l $fmt6, ..., l %r6)
 
 	%r7 =:st7 call $t7()
 	%s7 =s loads %r7
 	%d71 =d exts %s7
 	%r78 =l add %r7, 8
 	%d72 =d loadd %r78
-	%i7 =w call $printf(l $fmt7, d %d71, d %d72, ...)
+	%i7 =w call $printf(l $fmt7, ..., d %d71, d %d72)
 
 	%r8 =:st8 call $t8()
 	%r84 =l add 4, %r8
@@ -69,14 +69,14 @@ function $test() {
 	%w82 =w loadw %r84
 	%w83 =w loadw %r88
 	%w84 =w loadw %r812
-	%i8 =w call $printf(l $fmt8, w %w81, w %w82, w %w83, w %w84, ...)
+	%i8 =w call $printf(l $fmt8, ..., w %w81, w %w82, w %w83, w %w84)
 
 	%r9 =:st9 call $t9()
 	%r94 =l add 4, %r9
 	%w9 =w loadw %r9
 	%s9 =s loads %r94
 	%d9 =d exts %s9
-	%i9 =w call $printf(l $fmt9, w %w9, d %d9, ...)
+	%i9 =w call $printf(l $fmt9, ..., w %w9, d %d9)
 
 	ret
 }
diff --git a/test/abi6.ssa b/test/abi6.ssa
index 0870031..da2370c 100644
--- a/test/abi6.ssa
+++ b/test/abi6.ssa
@@ -13,8 +13,8 @@ function $f(:hfa3 %h1, :hfa3 %h2, d %d1, :hfa3 %h3, d %d2) {
         call $phfa3(:hfa3 %h1)
         call $phfa3(:hfa3 %h2)
         call $phfa3(:hfa3 %h3)
-        call $printf(l $dfmt, d %d1, ...)
-        call $printf(l $dfmt, d %d2, ...)
+        call $printf(l $dfmt, ..., d %d1)
+        call $printf(l $dfmt, ..., d %d2)
         ret
 }
 
diff --git a/test/echo.ssa b/test/echo.ssa
index 6010986..5e48b0e 100644
--- a/test/echo.ssa
+++ b/test/echo.ssa
@@ -20,7 +20,7 @@ function w $main(w %argc, l %argv) {
 @loop2
 	%sep =w phi @last 10, @nolast 32
 	%arg =l loadl %av
-	%r =w call $printf(l %fmt, l %arg, w %sep, ...)
+	%r =w call $printf(l %fmt, ..., l %arg, w %sep)
 	%av1 =l add %av, 8
 	%ac1 =w sub %ac, 1
 	jmp @loop
diff --git a/test/vararg2.ssa b/test/vararg2.ssa
index 7e85774..0b2eb53 100644
--- a/test/vararg2.ssa
+++ b/test/vararg2.ssa
@@ -19,11 +19,11 @@ export function $qbeprint0(l %fmt, ...) {
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)
@@ -59,11 +59,11 @@ export function $qbeprint1(w %argw0, l %fmt, ...) {
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)
@@ -99,11 +99,11 @@ export function $qbeprint2(d %argd0, l %fmt, ...) {
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)
@@ -139,11 +139,11 @@ export function $qbeprint3(w %argw0, w %argw1, w %argw2, w %argw3, l %fmt, ...)
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)
@@ -179,11 +179,11 @@ export function $qbeprint4(d %argd0, d %argd1, d %argd2, d %argd3, d %argd4, d %
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)
@@ -219,11 +219,11 @@ export function $qbeprint5(w %argw0, w %argw1, w %argw2, w %argw3, w %argw4, d %
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)
@@ -259,11 +259,11 @@ export function $qbeprint6(w %argw0, w %argw1, w %argw2, w %argw3, w %argw4, w %
 	jnz %isg, @casef, @cased
 @casef
 	%dbl =d vaarg %vp
-	%r =w call $printf(l %fmtdbl, d %dbl, ...)
+	%r =w call $printf(l %fmtdbl, ..., d %dbl)
 	jmp @loop
 @cased
 	%int =w vaarg %vp
-	%r =w call $printf(l %fmtint, w %int, ...)
+	%r =w call $printf(l %fmtint, ..., w %int)
 	jmp @loop
 @end
 	%r =w call $puts(l %emptys)