MIPS: XPA: Use XPA instructions in assembly
Utilise XPA instructions MFHC0 & MTHC0 in inline assembly instead of directly encoding them with the _ASM_INSN* macros, and transparently implement these instructions as assembler macros if the toolchain doesn't support them natively, using the recently introduced assembler macro helpers. The old direct encodings were restricted to using the register $at, so this allows the extra register moves to go away (saving a grand total of 24 bytes). Signed-off-by: James Hogan <jhogan@kernel.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/17775/
This commit is contained in:
Родитель
ed21e00777
Коммит
8e4789d288
|
@ -216,6 +216,12 @@ cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA
|
|||
endif
|
||||
toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt)
|
||||
cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT
|
||||
# For -mmicromips, use -Wa,-fatal-warnings to catch unsupported -mxpa which
|
||||
# only warns
|
||||
xpa-cflags-y := $(mips-cflags)
|
||||
xpa-cflags-$(micromips-ase) += -mmicromips -Wa$(comma)-fatal-warnings
|
||||
toolchain-xpa := $(call cc-option-yn,$(xpa-cflags-y) -mxpa)
|
||||
cflags-$(toolchain-xpa) += -DTOOLCHAIN_SUPPORTS_XPA
|
||||
|
||||
#
|
||||
# Firmware support
|
||||
|
|
|
@ -1504,18 +1504,27 @@ do { \
|
|||
local_irq_restore(__flags); \
|
||||
} while (0)
|
||||
|
||||
#ifndef TOOLCHAIN_SUPPORTS_XPA
|
||||
_ASM_MACRO_2R_1S(mfhc0, rt, rs, sel,
|
||||
_ASM_INSN_IF_MIPS(0x40400000 | __rt << 16 | __rs << 11 | \\sel)
|
||||
_ASM_INSN32_IF_MM(0x000000f4 | __rt << 21 | __rs << 16 | \\sel << 11));
|
||||
_ASM_MACRO_2R_1S(mthc0, rt, rd, sel,
|
||||
_ASM_INSN_IF_MIPS(0x40c00000 | __rt << 16 | __rd << 11 | \\sel)
|
||||
_ASM_INSN32_IF_MM(0x000002f4 | __rt << 21 | __rd << 16 | \\sel << 11));
|
||||
#define _ASM_SET_XPA ""
|
||||
#else /* !TOOLCHAIN_SUPPORTS_XPA */
|
||||
#define _ASM_SET_XPA ".set\txpa\n\t"
|
||||
#endif
|
||||
|
||||
#define __readx_32bit_c0_register(source) \
|
||||
({ \
|
||||
unsigned int __res; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" .set mips32r2 \n" \
|
||||
" # mfhc0 $1, %1 \n" \
|
||||
_ASM_INSN_IF_MIPS(0x40410000 | ((%1 & 0x1f) << 11)) \
|
||||
_ASM_INSN32_IF_MM(0x002000f4 | ((%1 & 0x1f) << 16)) \
|
||||
" move %0, $1 \n" \
|
||||
_ASM_SET_XPA \
|
||||
" mfhc0 %0, $%1 \n" \
|
||||
" .set pop \n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (source)); \
|
||||
|
@ -1526,12 +1535,9 @@ do { \
|
|||
do { \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
" .set mips32r2 \n" \
|
||||
" move $1, %0 \n" \
|
||||
" # mthc0 $1, %1 \n" \
|
||||
_ASM_INSN_IF_MIPS(0x40c10000 | ((%1 & 0x1f) << 11)) \
|
||||
_ASM_INSN32_IF_MM(0x002002f4 | ((%1 & 0x1f) << 16)) \
|
||||
_ASM_SET_XPA \
|
||||
" mthc0 %0, $%1 \n" \
|
||||
" .set pop \n" \
|
||||
: \
|
||||
: "r" (value), "i" (register)); \
|
||||
|
|
Загрузка…
Ссылка в новой задаче