Branch data Line data Source code
1 : : #ifndef __ASM_ARM_COMPILER_H
2 : : #define __ASM_ARM_COMPILER_H
3 : :
4 : : /*
5 : : * This is used to ensure the compiler did actually allocate the register we
6 : : * asked it for some inline assembly sequences. Apparently we can't trust
7 : : * the compiler from one version to another so a bit of paranoia won't hurt.
8 : : * This string is meant to be concatenated with the inline asm string and
9 : : * will cause compilation to stop on mismatch.
10 : : * (for details, see gcc PR 15089)
11 : : */
12 : : #define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
13 : :
14 : : #if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6)
15 : : /*
16 : : * Read TPIDRPRW.
17 : : * GCC requires a workaround as it does not treat a "memory" clobber on a
18 : : * non-volatile asm block as a side-effect.
19 : : * We want to allow caching the value, so for GCC avoid using volatile and
20 : : * instead use a fake stack read to hazard against barrier().
21 : : */
22 : : #if defined(__clang__)
23 : : static inline unsigned long read_TPIDRPRW(void)
24 : : {
25 : : unsigned long off;
26 : :
27 : : /*
28 : : * Read TPIDRPRW.
29 : : */
30 : : asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : : "memory");
31 : :
32 : : return off;
33 : : }
34 : : #else
35 : : static inline unsigned long read_TPIDRPRW(void)
36 : : {
37 : : unsigned long off;
38 : : register unsigned long *sp asm ("sp");
39 : :
40 : 1670750378 : asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp));
41 : :
42 : : return off;
43 : : }
44 : : #endif
45 : : #endif
46 : :
47 : : #endif /* __ASM_ARM_COMPILER_H */
|