This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Post-increment constraint in inline assembly (SuperH)


On 01/29/2018 05:57 PM, Georg-Johann Lay wrote:
On 29.01.2018 14:19, Oleg Endo wrote:
The problem (or rather disadvantage) with this approach is that the
compiler doesn't know what the value of "src" is after it has been
modified by the asm code.  Segher's suggestion looks like the better
option.

I think Segher's option is technically the way to go, except (as you pointed out) it doesn't /ensure/ that the compiler will use post-increment.

On the other hand, syntactically forcing the compiler to use post-increment prevents it from optimizing my function in another way. Getting in its way is (from my experience) usually not a good idea.

The "m>"(*src) operand doesn't even express that src is changing, and the constraint allows to use post-increment, but does not force it.

How could GCC choose post-increment in this situation? The documentation says that using an operand which is under the ">" constraint in multiple instructions isn't valid. Does "*src" not count as a use of "src"?

Now, what would happen if GCC decided to use post-increment mode for "m>"(*src)? Would that interfere with the way src opaquely changes because of the "+r"(src) constraint?

Moreover, the explicit usage of src+1 might add additional overhead; it's clear that the respective operation "p = src+1;" should not be optimized away to have an effect, but /if/ is has an effect then this might be an overhead (which Sébastien wanted to get rid of).

Well, the problem I'm originally set out to solve is writing a decent memcpy() function for unaligned source/destination pairs. I should have mentioned it sooner (wild XY problem draws near).

I can see what you suggest: the compiler may choose plain dereferencing and add another instruction to perform increment src afterwards. It does so until -O2.

I don't /really/ like not knowing whether the compiler will generate the code I planned, but in the worst-case situation I can still write my trivial function in assembler and enable LTO.



Right now I will stick to Segher's solution, partly because it behaves better while compiling - see my attached filed for the test case.

I'll still remember the trick. Thank you all for your insights!

Regards,
Sébastien
long *src;
long *dst;

void f(void)
{
	long longword;

	/* Segher's version */
	__asm__(
		"movua.l %1, %0"
		: "=z" (longword)
		: "m>" (*src)
	);

	/* Johann's version
	__asm__(
		"movua.l @%1+, %0"
		: "=z" (longword), "+r" (src)
		: "m>" (*src)
	); */

	*dst = longword;
	src++;
}

/* Segher's version:
	.type	_f, @function
_f:
	mov.l	_dst, r3
	mov.l	_src, r2
	mov.l	@r3, r3
	mov.l	@r2, r1
! 9 "movua.c" 1
	movua.l @r1+, r0
! 0 "" 2
	mov.l	r0, @r3
	rts
	mov.l	r1, @r2
*/

/* Johann's version:
_f:
	mov.l	_src, r2
	mov.l	@r2, r1
! 16 "movua.c" 1
	movua.l @r1+, r0
! 0 "" 2
	mov.l	r1, @r2
	mov.l	_dst, r1
	mov.l	@r1, r1
	mov.l	r0, @r1
	mov.l	@r2, r1
	add	#4, r1
	rts
	mov.l	r1, @r2
*/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]