Commit cd9e1927 authored by Marc Zyngier's avatar Marc Zyngier Committed by Catalin Marinas

arm64: Work around broken .inst when defective gas is detected

.inst being largely broken with older binutils, it'd be better not
to emit it altogether when detecting such configuration (as it
leads to all kind of horrors when using alternatives).

Generalize the __emit_inst macro and use it extensively in
asm/sysreg.h, and make it generate a .long when a broken gas is
detected. The disassembly will be crap, but at least we can write
semi-sane code.
Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent bbb56c27
...@@ -35,12 +35,33 @@ ...@@ -35,12 +35,33 @@
#define sys_reg(op0, op1, crn, crm, op2) \ #define sys_reg(op0, op1, crn, crm, op2) \
((((op0)&3)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5)) ((((op0)&3)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
#ifndef CONFIG_BROKEN_GAS_INST
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
#define __emit_inst(x) .inst (x) #define __emit_inst(x) .inst (x)
#else #else
#define __emit_inst(x) ".inst " __stringify((x)) "\n\t" #define __emit_inst(x) ".inst " __stringify((x)) "\n\t"
#endif #endif
#else /* CONFIG_BROKEN_GAS_INST */
#ifndef CONFIG_CPU_BIG_ENDIAN
#define __INSTR_BSWAP(x) (x)
#else /* CONFIG_CPU_BIG_ENDIAN */
#define __INSTR_BSWAP(x) ((((x) << 24) & 0xff000000) | \
(((x) << 8) & 0x00ff0000) | \
(((x) >> 8) & 0x0000ff00) | \
(((x) >> 24) & 0x000000ff))
#endif /* CONFIG_CPU_BIG_ENDIAN */
#ifdef __ASSEMBLY__
#define __emit_inst(x) .long __INSTR_BSWAP(x)
#else /* __ASSEMBLY__ */
#define __emit_inst(x) ".long " __stringify(__INSTR_BSWAP(x)) "\n\t"
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_BROKEN_GAS_INST */
#define SYS_MIDR_EL1 sys_reg(3, 0, 0, 0, 0) #define SYS_MIDR_EL1 sys_reg(3, 0, 0, 0, 0)
#define SYS_MPIDR_EL1 sys_reg(3, 0, 0, 0, 5) #define SYS_MPIDR_EL1 sys_reg(3, 0, 0, 0, 5)
#define SYS_REVIDR_EL1 sys_reg(3, 0, 0, 0, 6) #define SYS_REVIDR_EL1 sys_reg(3, 0, 0, 0, 6)
...@@ -232,11 +253,11 @@ ...@@ -232,11 +253,11 @@
.equ .L__reg_num_xzr, 31 .equ .L__reg_num_xzr, 31
.macro mrs_s, rt, sreg .macro mrs_s, rt, sreg
.inst 0xd5200000|(\sreg)|(.L__reg_num_\rt) __emit_inst(0xd5200000|(\sreg)|(.L__reg_num_\rt))
.endm .endm
.macro msr_s, sreg, rt .macro msr_s, sreg, rt
.inst 0xd5000000|(\sreg)|(.L__reg_num_\rt) __emit_inst(0xd5000000|(\sreg)|(.L__reg_num_\rt))
.endm .endm
#else #else
...@@ -250,11 +271,11 @@ asm( ...@@ -250,11 +271,11 @@ asm(
" .equ .L__reg_num_xzr, 31\n" " .equ .L__reg_num_xzr, 31\n"
"\n" "\n"
" .macro mrs_s, rt, sreg\n" " .macro mrs_s, rt, sreg\n"
" .inst 0xd5200000|(\\sreg)|(.L__reg_num_\\rt)\n" __emit_inst(0xd5200000|(\\sreg)|(.L__reg_num_\\rt))
" .endm\n" " .endm\n"
"\n" "\n"
" .macro msr_s, sreg, rt\n" " .macro msr_s, sreg, rt\n"
" .inst 0xd5000000|(\\sreg)|(.L__reg_num_\\rt)\n" __emit_inst(0xd5000000|(\\sreg)|(.L__reg_num_\\rt))
" .endm\n" " .endm\n"
); );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment