ARM: 7493/1: use generic unaligned.h

This moves ARM over to the asm-generic/unaligned.h header. This has the
benefit of better code generated especially for ARMv7 on gcc 4.7+
compilers.

As Arnd Bergmann, points out: The asm-generic version uses the struct
version for native-endian unaligned access and the byteshift version
for the opposite endianess. The current ARM version however uses the
byteshift implementation for both.

Thanks to Nicolas Pitre for the excellent analysis:

Test case:

int foo (int *x) { return get_unaligned(x); }
long long bar (long long *x) { return get_unaligned(x); }

With the current ARM version:

foo:
ldrbr3, [r0, #2]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 2B], MEM[(const u8 *)x_1(D) + 2B]
ldrbr1, [r0, #1]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 1B], MEM[(const u8 *)x_1(D) + 1B]
ldrbr2, [r0, #0]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D)], MEM[(const u8 *)x_1(D)]
movr3, r3, asl #16@ tmp154, MEM[(const u8 *)x_1(D) + 2B],
ldrbr0, [r0, #3]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 3B], MEM[(const u8 *)x_1(D) + 3B]
orrr3, r3, r1, asl #8@, tmp155, tmp154, MEM[(const u8 *)x_1(D) + 1B],
orrr3, r3, r2@ tmp157, tmp155, MEM[(const u8 *)x_1(D)]
orrr0, r3, r0, asl #24@,, tmp157, MEM[(const u8 *)x_1(D) + 3B],
bxlr@

bar:
movr2, #0@ tmp184,
ldrbr5, [r0, #6]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 6B], MEM[(const u8 *)x_1(D) + 6B]
ldrbr4, [r0, #5]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 5B], MEM[(const u8 *)x_1(D) + 5B]
ldrbip, [r0, #2]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 2B], MEM[(const u8 *)x_1(D) + 2B]
ldrbr1, [r0, #4]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 4B], MEM[(const u8 *)x_1(D) + 4B]
movr5, r5, asl #16@ tmp175, MEM[(const u8 *)x_1(D) + 6B],
ldrbr7, [r0, #1]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 1B], MEM[(const u8 *)x_1(D) + 1B]
orrr5, r5, r4, asl #8@, tmp176, tmp175, MEM[(const u8 *)x_1(D) + 5B],
ldrbr6, [r0, #7]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 7B], MEM[(const u8 *)x_1(D) + 7B]
orrr5, r5, r1@ tmp178, tmp176, MEM[(const u8 *)x_1(D) + 4B]
ldrbr4, [r0, #0]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D)], MEM[(const u8 *)x_1(D)]
movip, ip, asl #16@ tmp188, MEM[(const u8 *)x_1(D) + 2B],
ldrbr1, [r0, #3]@ zero_extendqisi2@ MEM[(const u8 *)x_1(D) + 3B], MEM[(const u8 *)x_1(D) + 3B]
orrip, ip, r7, asl #8@, tmp189, tmp188, MEM[(const u8 *)x_1(D) + 1B],
orrr3, r5, r6, asl #24@,, tmp178, MEM[(const u8 *)x_1(D) + 7B],
orrip, ip, r4@ tmp191, tmp189, MEM[(const u8 *)x_1(D)]
orrip, ip, r1, asl #24@, tmp194, tmp191, MEM[(const u8 *)x_1(D) + 3B],
movr1, r3@,
orrr0, r2, ipc/@ tmp171, tmp184, tmp194
bxlr

In both cases the code is slightly suboptimal.  One may wonder why
wasting r2 with the constant 0 in the second case for example.  And all
the mov's could be folded in subsequent orr's, etc.

Now with the asm-generic version:

foo:
ldrr0, [r0, #0]@ unaligned@,* x
bxlr@

bar:
movr3, r0@ x, x
ldrr0, [r0, #0]@ unaligned@,* x
ldrr1, [r3, #4]@ unaligned@,
bxlr@

This is way better of course, but only because this was compiled for
ARMv7. In this case the compiler knows that the hardware can do
unaligned word access.  This isn't that obvious for foo(), but if we
remove the get_unaligned() from bar as follows:

long long bar (long long *x) {return *x; }

then the resulting code is:

bar:
ldmiar0, {r0, r1}@ x,,
bxlr@

So this proves that the presumed aligned vs unaligned cases does have
influence on the instructions the compiler may use and that the above
unaligned code results are not just an accident.

Still... this isn't fully conclusive without at least looking at the
resulting assembly fron a pre ARMv6 compilation.  Let's see with an
ARMv5 target:

foo:
ldrbr3, [r0, #0]@ zero_extendqisi2@ tmp139,* x
ldrbr1, [r0, #1]@ zero_extendqisi2@ tmp140,
ldrbr2, [r0, #2]@ zero_extendqisi2@ tmp143,
ldrbr0, [r0, #3]@ zero_extendqisi2@ tmp146,
orrr3, r3, r1, asl #8@, tmp142, tmp139, tmp140,
orrr3, r3, r2, asl #16@, tmp145, tmp142, tmp143,
orrr0, r3, r0, asl #24@,, tmp145, tmp146,
bxlr@

bar:
ldrbr2, [r0, #0]@ zero_extendqisi2@ tmp139,* x
ldrbr7, [r0, #1]@ zero_extendqisi2@ tmp140,
ldrbr3, [r0, #4]@ zero_extendqisi2@ tmp149,
ldrbr6, [r0, #5]@ zero_extendqisi2@ tmp150,
ldrbr5, [r0, #2]@ zero_extendqisi2@ tmp143,
ldrbr4, [r0, #6]@ zero_extendqisi2@ tmp153,
ldrbr1, [r0, #7]@ zero_extendqisi2@ tmp156,
ldrbip, [r0, #3]@ zero_extendqisi2@ tmp146,
orrr2, r2, r7, asl #8@, tmp142, tmp139, tmp140,
orrr3, r3, r6, asl #8@, tmp152, tmp149, tmp150,
orrr2, r2, r5, asl #16@, tmp145, tmp142, tmp143,
orrr3, r3, r4, asl #16@, tmp155, tmp152, tmp153,
orrr0, r2, ip, asl #24@,, tmp145, tmp146,
orrr1, r3, r1, asl #24@,, tmp155, tmp156,
bxlr

Compared to the initial results, this is really nicely optimized and I
couldn't do much better if I were to hand code it myself.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
modified for Mako from kernel.org reference

Signed-off-by: faux123 <reioux@gmail.com>

Conflicts:
arch/arm/include/asm/unaligned.h

Conflicts:

arch/arm/include/asm/unaligned.h