Re: [RFC PATCH v3] MIPS: fix build with binutils 2.24.51+

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(top posting so Matthew can see the entire patch)

+CC Matthew Fortune who has some comments on the patch.

On 10/11/2014 11:09 AM, Manuel Lauss wrote:
> Starting with version 2.24.51.20140728 MIPS binutils complain loudly
> about mixing soft-float and hard-float object files, leading to this
> build failure since GCC is invoked with "-msoft-float" on MIPS:
> 
> {standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
>   LD      arch/mips/alchemy/common/built-in.o
> mipsel-softfloat-linux-gnu-ld: Warning: arch/mips/alchemy/common/built-in.o
>  uses -msoft-float (set by arch/mips/alchemy/common/prom.o),
>  arch/mips/alchemy/common/sleeper.o uses -mhard-float
> 
> To fix this, we detect if GAS is new enough to support "-msoft-float" command
> option, and if it does, we can let GCC pass it to GAS;  but then we also need
> to sprinkle the files which make use of floating point registers with the
> necessary ".set hardfloat" directives.
> 
> Signed-off-by: Manuel Lauss <manuel.lauss@xxxxxxxxx>
> ---
> I've only tested a mips32r1 build, but at least binutils-2.23 and a
> snapshot from today (with the MIPS fp changes) compile a bootable
> kernel.
> 
> Tests on 64bit and with MSA and other extensions also appreciated!
> 
> v3: incorporate Maciej's suggestions:
> 	- detect if gas can handle -msoft-float and ".set hardfloat"
> 	- apply .set hardfloat only where really necessary
> 
> v2: cover more files
> 
> This was introduced in binutils commit  351cdf24d223290b15fa991e5052ec9e9bd1e284
> ("[MIPS] Implement O32 FPXX, FP64 and FP64A ABI extensions").
> 
>  arch/mips/Makefile                  |  9 +++++++++
>  arch/mips/include/asm/asmmacro-32.h |  5 +++++
>  arch/mips/include/asm/asmmacro.h    | 18 ++++++++++++++++++
>  arch/mips/include/asm/fpregdef.h    | 14 ++++++++++++++
>  arch/mips/include/asm/mipsregs.h    | 19 +++++++++++++++++++
>  arch/mips/kernel/genex.S            |  1 +
>  arch/mips/kernel/r2300_switch.S     |  5 +++++
>  arch/mips/kernel/r4k_fpu.S          |  7 +++++++
>  arch/mips/kernel/r4k_switch.S       |  9 +++++++++
>  arch/mips/kernel/r6000_fpu.S        |  5 +++++
>  10 files changed, 92 insertions(+)
> 
> diff --git a/arch/mips/Makefile b/arch/mips/Makefile
> index bbac51e1..35005e1 100644
> --- a/arch/mips/Makefile
> +++ b/arch/mips/Makefile
> @@ -93,6 +93,15 @@ LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
>  KBUILD_AFLAGS_MODULE		+= -mlong-calls
>  KBUILD_CFLAGS_MODULE		+= -mlong-calls
> 
> +#
> +# pass -msoft-float to GAS if it supports it.  However on newer binutils
> +# (specifically newer than 2.24.51.20140728) we then also need to explicitly
> +# set ".set hardfloat" in all files which manipulate floating point registers.
> +#
> +ifneq ($(call as-option,-Wa$(comma)-msoft-float,),)
> +	cflags-y		+= -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float
> +endif
> +
>  cflags-y += -ffreestanding
> 
>  #
> diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h
> index e38c281..a97ce53 100644
> --- a/arch/mips/include/asm/asmmacro-32.h
> +++ b/arch/mips/include/asm/asmmacro-32.h
> @@ -12,6 +12,9 @@
>  #include <asm/fpregdef.h>
>  #include <asm/mipsregs.h>
> 
> +	.set push
> +	SET_HARDFLOAT
> +
>  	.macro	fpu_save_single thread tmp=t0
>  	cfc1	\tmp,  fcr31
>  	swc1	$f0,  THREAD_FPR0_LS64(\thread)
> @@ -86,6 +89,8 @@
>  	ctc1	\tmp, fcr31
>  	.endm
> 
> +	.set pop
> +
>  	.macro	cpu_save_nonscratch thread
>  	LONG_S	s0, THREAD_REG16(\thread)
>  	LONG_S	s1, THREAD_REG17(\thread)
> diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
> index cd9a98b..6caf876 100644
> --- a/arch/mips/include/asm/asmmacro.h
> +++ b/arch/mips/include/asm/asmmacro.h
> @@ -57,6 +57,8 @@
>  #endif /* CONFIG_CPU_MIPSR2 */
> 
>  	.macro	fpu_save_16even thread tmp=t0
> +	.set	push
> +	SET_HARDFLOAT
>  	cfc1	\tmp, fcr31
>  	sdc1	$f0,  THREAD_FPR0_LS64(\thread)
>  	sdc1	$f2,  THREAD_FPR2_LS64(\thread)
> @@ -75,11 +77,13 @@
>  	sdc1	$f28, THREAD_FPR28_LS64(\thread)
>  	sdc1	$f30, THREAD_FPR30_LS64(\thread)
>  	sw	\tmp, THREAD_FCR31(\thread)
> +	.set	pop
>  	.endm
> 
>  	.macro	fpu_save_16odd thread
>  	.set	push
>  	.set	mips64r2
> +	SET_HARDFLOAT
>  	sdc1	$f1,  THREAD_FPR1_LS64(\thread)
>  	sdc1	$f3,  THREAD_FPR3_LS64(\thread)
>  	sdc1	$f5,  THREAD_FPR5_LS64(\thread)
> @@ -110,6 +114,8 @@
>  	.endm
> 
>  	.macro	fpu_restore_16even thread tmp=t0
> +	.set	push
> +	SET_HARDFLOAT
>  	lw	\tmp, THREAD_FCR31(\thread)
>  	ldc1	$f0,  THREAD_FPR0_LS64(\thread)
>  	ldc1	$f2,  THREAD_FPR2_LS64(\thread)
> @@ -133,6 +139,7 @@
>  	.macro	fpu_restore_16odd thread
>  	.set	push
>  	.set	mips64r2
> +	SET_HARDFLOAT
>  	ldc1	$f1,  THREAD_FPR1_LS64(\thread)
>  	ldc1	$f3,  THREAD_FPR3_LS64(\thread)
>  	ldc1	$f5,  THREAD_FPR5_LS64(\thread)
> @@ -277,6 +284,7 @@
>  	.macro	cfcmsa	rd, cs
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	.insn
>  	.word	CFC_MSA_INSN | (\cs << 11)
>  	move	\rd, $1
> @@ -286,6 +294,7 @@
>  	.macro	ctcmsa	cd, rs
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	move	$1, \rs
>  	.word	CTC_MSA_INSN | (\cd << 6)
>  	.set	pop
> @@ -294,6 +303,7 @@
>  	.macro	ld_d	wd, off, base
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	add	$1, \base, \off
>  	.word	LDD_MSA_INSN | (\wd << 6)
>  	.set	pop
> @@ -302,6 +312,7 @@
>  	.macro	st_d	wd, off, base
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	add	$1, \base, \off
>  	.word	STD_MSA_INSN | (\wd << 6)
>  	.set	pop
> @@ -310,6 +321,7 @@
>  	.macro	copy_u_w	rd, ws, n
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	.insn
>  	.word	COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
>  	/* move triggers an assembler bug... */
> @@ -320,6 +332,7 @@
>  	.macro	copy_u_d	rd, ws, n
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	.insn
>  	.word	COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
>  	/* move triggers an assembler bug... */
> @@ -330,6 +343,7 @@
>  	.macro	insert_w	wd, n, rs
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	/* move triggers an assembler bug... */
>  	or	$1, \rs, zero
>  	.word	INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
> @@ -339,6 +353,7 @@
>  	.macro	insert_d	wd, n, rs
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	/* move triggers an assembler bug... */
>  	or	$1, \rs, zero
>  	.word	INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
> @@ -381,6 +396,7 @@
>  	st_d	31, THREAD_FPR31, \thread
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	cfcmsa	$1, MSA_CSR
>  	sw	$1, THREAD_MSA_CSR(\thread)
>  	.set	pop
> @@ -389,6 +405,7 @@
>  	.macro	msa_restore_all	thread
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	lw	$1, THREAD_MSA_CSR(\thread)
>  	ctcmsa	MSA_CSR, $1
>  	.set	pop
> @@ -441,6 +458,7 @@
>  	.macro	msa_init_all_upper
>  	.set	push
>  	.set	noat
> +	SET_HARDFLOAT
>  	not	$1, zero
>  	msa_init_upper	0
>  	.set	pop
> diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h
> index 429481f..f184ba0 100644
> --- a/arch/mips/include/asm/fpregdef.h
> +++ b/arch/mips/include/asm/fpregdef.h
> @@ -14,6 +14,20 @@
> 
>  #include <asm/sgidefs.h>
> 
> +/*
> + * starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing
> + * hardfloat and softfloat object files.  The kernel build uses soft-float by
> + * default, so we also need to pass -msoft-float along to GAS if it supports it.
> + * But this in turn causes assembler errors in files which access hardfloat
> + * registers.  We detect if GAS supports "-msoft-float" in the Makefile and
> + * explicitly put ".set hardfloat" where floating point registers are touched.
> + */
> +#ifdef GAS_HAS_SET_HARDFLOAT
> +#define SET_HARDFLOAT .set hardfloat
> +#else
> +#define SET_HARDFLOAT
> +#endif
> +
>  #if _MIPS_SIM == _MIPS_SIM_ABI32
> 
>  /*
> diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
> index cf3b580..889c012 100644
> --- a/arch/mips/include/asm/mipsregs.h
> +++ b/arch/mips/include/asm/mipsregs.h
> @@ -1324,6 +1324,7 @@ do {									\
>  /*
>   * Macros to access the floating point coprocessor control registers
>   */
> +#ifdef GAS_HAS_SET_HARDFLOAT
>  #define read_32bit_cp1_register(source)					\
>  ({									\
>  	int __res;							\
> @@ -1334,11 +1335,29 @@ do {									\
>  	"	# gas fails to assemble cfc1 for some archs,	\n"	\
>  	"	# like Octeon.					\n"	\
>  	"	.set	mips1					\n"	\
> +	"	.set	hardfloat				\n"	\
>  	"	cfc1	%0,"STR(source)"			\n"	\
>  	"	.set	pop					\n"	\
>  	: "=r" (__res));						\
>  	__res;								\
>  })
> +#else
> +#define read_32bit_cp1_register(source)					\
> +({									\
> +	int __res;							\
> +									\
> +	__asm__ __volatile__(						\
> +	"	.set	push					\n"	\
> +	"	.set	reorder					\n"	\
> +	"	# gas fails to assemble cfc1 for some archs,	\n"	\
> +	"	# like Octeon.					\n"	\
> +	"	.set	mips1					\n"	\
> +	"	cfc1	%0,"STR(source)"			\n"	\
> +	"	.set	pop					\n"	\
> +	: "=r" (__res));						\
> +	__res;								\
> +})
> +#endif
> 
>  #ifdef HAVE_AS_DSP
>  #define rddsp(mask)							\
> diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
> index ac35e12..a5e26dd 100644
> --- a/arch/mips/kernel/genex.S
> +++ b/arch/mips/kernel/genex.S
> @@ -358,6 +358,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
>  	.set	push
>  	/* gas fails to assemble cfc1 for some archs (octeon).*/ \
>  	.set	mips1
> +	SET_HARDFLOAT
>  	cfc1	a1, fcr31
>  	li	a2, ~(0x3f << 12)
>  	and	a2, a1
> diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
> index 20b7b04..435ea65 100644
> --- a/arch/mips/kernel/r2300_switch.S
> +++ b/arch/mips/kernel/r2300_switch.S
> @@ -120,6 +120,9 @@ LEAF(_restore_fp)
> 
>  #define FPU_DEFAULT  0x00000000
> 
> +	.set push
> +	SET_HARDFLOAT
> +
>  LEAF(_init_fpu)
>  	mfc0	t0, CP0_STATUS
>  	li	t1, ST0_CU1
> @@ -165,3 +168,5 @@ LEAF(_init_fpu)
>  	mtc1	t0, $f31
>  	jr	ra
>  	END(_init_fpu)
> +
> +	.set pop
> diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
> index 8352523..4a827a3 100644
> --- a/arch/mips/kernel/r4k_fpu.S
> +++ b/arch/mips/kernel/r4k_fpu.S
> @@ -21,6 +21,7 @@
> 
>  	.macro	EX insn, reg, src
>  	.set	push
> +	SET_HARDFLOAT
>  	.set	nomacro
>  .ex\@:	\insn	\reg, \src
>  	.set	pop
> @@ -33,7 +34,10 @@
>  	.set	arch=r4000
> 
>  LEAF(_save_fp_context)
> +	.set	push
> +	SET_HARDFLOAT
>  	cfc1	t1, fcr31
> +	.set	pop
> 
>  #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
>  	.set	push
> @@ -191,7 +195,10 @@ LEAF(_restore_fp_context)
>  	EX	ldc1 $f26, SC_FPREGS+208(a0)
>  	EX	ldc1 $f28, SC_FPREGS+224(a0)
>  	EX	ldc1 $f30, SC_FPREGS+240(a0)
> +	.set push
> +	SET_HARDFLOAT
>  	ctc1	t1, fcr31
> +	.set pop
>  	jr	ra
>  	 li	v0, 0					# success
>  	END(_restore_fp_context)
> diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
> index 4c4ec18..6467a8b 100644
> --- a/arch/mips/kernel/r4k_switch.S
> +++ b/arch/mips/kernel/r4k_switch.S
> @@ -65,8 +65,12 @@
>  	bgtz	a3, 1f
> 
>  	/* Save 128b MSA vector context + scalar FP control & status. */
> +	.set push
> +	SET_HARDFLOAT
>  	cfc1	t1, fcr31
>  	msa_save_all	a0
> +	.set pop	/* SET_HARDFLOAT */
> +
>  	sw	t1, THREAD_FCR31(a0)
>  	b	2f
> 
> @@ -161,6 +165,9 @@ LEAF(_init_msa_upper)
> 
>  #define FPU_DEFAULT  0x00000000
> 
> +	.set push
> +	SET_HARDFLOAT
> +
>  LEAF(_init_fpu)
>  	mfc0	t0, CP0_STATUS
>  	li	t1, ST0_CU1
> @@ -291,3 +298,5 @@ LEAF(_init_fpu)
>  #endif
>  	jr	ra
>  	END(_init_fpu)
> +
> +	.set pop	/* SET_HARDFLOAT */
> diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
> index da0fbe4..4707738 100644
> --- a/arch/mips/kernel/r6000_fpu.S
> +++ b/arch/mips/kernel/r6000_fpu.S
> @@ -18,6 +18,9 @@
> 
>  	.set	noreorder
>  	.set	mips2
> +	.set	push
> +	SET_HARDFLOAT
> +
>  	/* Save floating point context */
>  	LEAF(_save_fp_context)
>  	mfc0	t0,CP0_STATUS
> @@ -85,3 +88,5 @@
>  1:	jr	ra
>  	 nop
>  	END(_restore_fp_context)
> +
> +	.set pop	/* SET_HARDFLOAT */
> --
> 2.1.2
> 
> 

-- 
markos





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux