forked from Minki/linux
ada63d4074
The __asmeq macro is used inside inline asm statements to ensure that register asm variables that explicitly specify a register are mapped correctly onto those registers when used in inline asm input and output constraints. However, the string based matching fails to take into account that 'fp' is often referred to as 'r11' and 'ip' is often referred to as 'r12', (e.g., by clang), causing false negatives. Fix this by making __asmeq consider the ("fp","r11"), ("r11","fp"), ("ip","r12") and ("r12","ip") cases specifically. Reviewed-by: Alex Elder <elder@linaro.org> Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
29 lines
939 B
C
29 lines
939 B
C
#ifndef __ASM_ARM_COMPILER_H
|
|
#define __ASM_ARM_COMPILER_H
|
|
|
|
/*
|
|
* This is used to ensure the compiler did actually allocate the register we
|
|
* asked it for some inline assembly sequences. Apparently we can't trust
|
|
* the compiler from one version to another so a bit of paranoia won't hurt.
|
|
* This string is meant to be concatenated with the inline asm string and
|
|
* will cause compilation to stop on mismatch.
|
|
* (for details, see gcc PR 15089)
|
|
* For compatibility with clang, we have to specifically take the equivalence
|
|
* of 'r11' <-> 'fp' and 'r12' <-> 'ip' into account as well.
|
|
*/
|
|
#define __asmeq(x, y) \
|
|
".ifnc " x "," y "; " \
|
|
".ifnc " x y ",fpr11; " \
|
|
".ifnc " x y ",r11fp; " \
|
|
".ifnc " x y ",ipr12; " \
|
|
".ifnc " x y ",r12ip; " \
|
|
".err; " \
|
|
".endif; " \
|
|
".endif; " \
|
|
".endif; " \
|
|
".endif; " \
|
|
".endif\n\t"
|
|
|
|
|
|
#endif /* __ASM_ARM_COMPILER_H */
|