[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lightning] Example with putarg

From: Marc Nieper-Wißkirchen
Subject: [Lightning] Example with putarg
Date: Thu, 07 Sep 2017 08:30:09 +0000

Hi Paulo,

I've did some more experiments with putarg. To recapitulate: The manual warns that register arguments have volatile values but does not specify exactly when the value may be overwritten.

In the factorial example in the manual, the following code snippet is contained:
putargr R0, ac          ! Update the accumulator
subi R1, R1, 1          ! argument -= 1
putargr R1, in          ! Update the argument
Thus, it is assumed that the "subi" instruction does not overwrite the value in "ac". But this is a very dangerous assumption.

If the constant 1 was replaced by a constant not fitting in a 32-bit-integer, at least on x64, a scratch register is needed, which may be taken from the list of argument registers. And in fact, the following (stupid) example produces "wrong" code on x64:

tramp 64

arg $a
arg $b
arg $c
arg $d
arg $e
arg $f

getarg %r0 $a
getarg %r1 $b
getarg %r(3) $c

putargr %r0 $d
putargr %r0 $e
putargr %r0 $f

putargr %r0 $c
subi %r1 %r1 123456789123456 // Overwrites %r9, which is $f
putargr %r1 $a
putargr %r2 $b

jmpr %r(3)

I see only two ways out here: Either the documentation should state that register arguments can be overwritten by *any* instruction except for "jmpr", "st(x)" and "ld(x)" (the latter are needed to transfer back the register arguments to non-volatile memory), or GNU lightning should make register arguments non-volatile if it cannot prove that they are dead.

In the first case, the factorial example should be rewritten, by moving the subi instruction before the first putargr.

The latter case is, in my opinion, a much better solution. First of all, it abstracts away part of the difference between register arguments and stack arguments because the latter are always non-volatile. Secondly, a GNU lightning's functions are modeled as C functions (without varargs, though), it would meet the expectation that arguments are preserved throughout a function (can be read using getarg and written using putarg, throughout) much like callee-saved register as arguments to C functions can also be accessed at any time.

(On machines with register arguments, this also allows user code to make use of these registers, which were otherwise mostly wasted.)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]