[MIPS] Implement O32 FPXX, FP64 and FP64A ABI extensions

Specification:
https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking

include/

	* elf/mips.h (PT_MIPS_ABIFLAGS, SHT_MIPS_ABIFLAGS): Define.
	(Val_GNU_MIPS_ABI_FP_OLD_64): Rename from Val_GNU_MIPS_ABI_FP_64.
	(Val_GNU_MIPS_ABI_FP_64): Redefine.
	(Val_GNU_MIPS_ABI_FP_XX): Define.
	(Elf_External_ABIFlags_v0, Elf_Internal_ABIFlags_v0): New structures.
	(AFL_REG_NONE, AFL_REG_32, AFL_REG_64, AFL_REG_128): Define.
	(AFL_ASE_DSP, AFL_ASE_DSPR2, AFL_ASE_EVA, AFL_ASE_MCU): Likewise.
	(AFL_ASE_MDMX, AFL_ASE_MIPS3D, AFL_ASE_MT, AFL_ASE_SMARTMIPS): Likewise.
	(AFL_ASE_VIRT, AFL_ASE_MSA, AFL_ASE_MIPS16): Likewise.
	(AFL_ASE_MICROMIPS, AFL_ASE_XPA): Likewise.
	(AFL_EXT_XLR, AFL_EXT_OCTEON2, AFL_EXT_OCTEONP): Likewise.
	(AFL_EXT_LOONGSON_3A, AFL_EXT_OCTEON, AFL_EXT_5900): Likewise.
	(AFL_EXT_4650, AFL_EXT_4010, AFL_EXT_4100, AFL_EXT_3900): Likewise.
	(AFL_EXT_10000, AFL_EXT_SB1, AFL_EXT_4111, AFL_EXT_4120): Likewise.
	(AFL_EXT_5400, AFL_EXT_5500, AFL_EXT_LOONGSON_2E): Likewise.
	(AFL_EXT_LOONGSON_2F): Likewise.
	(bfd_mips_elf_swap_abiflags_v0_in): Prototype.
	(bfd_mips_elf_swap_abiflags_v0_out): Likewise.
	(bfd_mips_isa_ext): Likewise.

bfd/

	* elfxx-mips.c (ABI_O32_P, MIPS_ELF_ABIFLAGS_SECTION_NAME_P): New macro.
	(mips_elf_obj_tdata): Add abiflags and abiflags_valid fields.
	(bfd_mips_elf_swap_abiflags_v0_in): New function.
	(bfd_mips_elf_swap_abiflags_v0_out): Likewise.
	(_bfd_mips_elf_section_from_shdr): Handle SHT_MIPS_ABIFLAGS.
	(_bfd_mips_elf_fake_sections): Likewise.
	(_bfd_mips_elf_always_size_sections): Handle .MIPS.abiflags.
	(_bfd_mips_elf_additional_program_headers): Account for new
	PT_MIPS_ABIFLAGS program header.
	(_bfd_mips_elf_modify_segment_map): Create PT_MIPS_ABIFLAGS segment and
	associate with .MIPS.abiflags.
	(_bfd_mips_elf_gc_mark_extra_sections): New function.
	(bfd_mips_isa_ext, update_mips_abiflags_isa): New static function.
	(infer_mips_abiflags): Likewise.
	(_bfd_mips_elf_final_link): Handle .MIPS.abiflags.
	(mips_32bit_flags_p): Moved higher.
	(mips_elf_merge_obj_attributes, _bfd_mips_fp_abi_string): Error
	checking for FP ABIs.
	(_bfd_mips_elf_merge_private_bfd_data): Restructure and add abiflags
	checks.  Check EF_MIPS_FP64 flag consistency.
	(print_mips_ases, print_mips_isa_ext): New static function.
	(print_mips_fp_abi_value, get_mips_reg_size): Likewise.
	(_bfd_mips_elf_print_private_bfd_data): Display abiflags data.
	(_bfd_mips_post_process_headers): Set EI_ABIVERSION = 3 for
	Val_GNU_MIPS_ABI_FP_64 or Val_GNU_MIPS_ABI_FP_64A.
	* elfxx-mips.h (_bfd_mips_elf_gc_mark_extra_sections): New prototype.
	* elf32-mips.c (elf_backend_gc_mark_extra_sections): Implement.
	* elfn32-mips.c (elf_backend_gc_mark_extra_sections): Implement.
	* elf64-mips.c (elf_backend_gc_mark_extra_sections): Implement.

binutils/

	* readelf.c (get_mips_segment_type): Display name for PT_MIPS_ABIFLAGS.
	(get_mips_section_type_name): Display name for SHT_MIPS_ABIFLAGS.
	(display_mips_gnu_attribute): Abstracted fp abi printing to...
	(print_mips_fp_abi_value): New static function. Handle new FP ABIs.
	(print_mips_ases, print_mips_isa_ext): New static functions.
	(get_mips_reg_size): Likewise.
	(process_mips_specific): Display abiflags data.

elfcpp/

	* elfcpp.h (PT_MIPS_ABIFLAGS): New program header type.

gas/

	* config/tc-mips.c (mips_flags_frag): New static global.
	(struct mips_set_options): Add oddspreg field.
	(file_mips_opts, mips_opts): Initialize oddspreg.
	(ISA_HAS_ODD_SINGLE_FPR): Add CPU argument and update for R5900 and
	Loongson-3a.
	(enum options, md_longopts, md_parse_option): Add -mfpxx, -modd-spreg
	and -mno-odd-spreg options.
	(md_begin): Create .MIPS.abiflags section.
	(fpabi_incompatible_with, fpabi_requires): New static function.
	(check_fpabi): Likewise.
	(mips_check_options): Handle fp=xx and oddspreg restrictions.
	(file_mips_check_options): Set oddspreg by default for fp=xx.
	(mips_oddfpreg_ok): Re-write function.
	(check_regno): Check odd numbered registers regardless of FPR size.
	For fp != 32 use as_bad instead of as_warn.
	(match_float_constant): Rewrite check regarding FP register width.  Add
	support for generating constants when MXHC1 is present.  Handle fp=xx
	to comply with the ABI.
	(macro): Update M_LI_DD similarly to match_float_constant.  Generate
	MTHC1 when available.  Check that correct code can be generated for
	fp=xx and fp=64 ABIs.
	(parse_code_option, s_mipsset): Add fp=xx, oddspreg and nooddspreg
	options.
	(mips_convert_ase_flags): New static function.
	(mips_elf_final_processing): Use fpabi == Val_GNU_MIPS_ABI_FP_OLD_64
	to determine when to add the EF_MIPS_FP64 flag.  Populate the
	.MIPS.abiflags section.
	(md_mips_end): Update .gnu_attribute based on command line and .module
	as applicable.  Use check_fpabi to ensure .gnu.attribute and command
	line/.module options are consistent.
	* doc/as.texinfo: Add missing -mgp64/-mfp64 options and document new
	-mfpxx, -modd-spreg and -mno-odd-spreg options.
	* doc/c-mips.texi: Document -mfpxx, -modd-spreg, -mno-odd-spreg,
	gnu_attribute values and FP ABIs.

ld/

	* emulparams/elf32bmip.sh: Add .MIPS.abiflags.
	* emulparams/elf32bmipn32-defs.sh: Likewise.
	* emulparams/elf64bmip-defs.sh: Likewise.

opcodes/

	* micromips-opc.c (COD, LCD) New macros.
	(cfc1, ctc1): Remove FP_S attribute.
	(dmfc1, mfc1, mfhc1): Add LCD attribute.
	(dmtc1, mtc1, mthc1): Add COD attribute.
	* mips-opc.c (cfc1, cftc1, ctc, cttc1): Remove FP_S attribute.

binutils/testsuite/

	* binutils-all/readelf.s: Account for .MIPS.abiflags and
	.gnu.attributes.
	* binutils-all/readelf.ss-tmips: Likewise.
	* binutils-all/strip-3.d: Likewise.

gas/testsuite/

	* gas/mips/attr-gnu-4-0.d: New.
	* gas/mips/attr-gnu-4-0.s: Likewise.
	* gas/mips/attr-gnu-4-1-mfp32.l: Likewise.
	* gas/mips/attr-gnu-4-1-mfp32.s: Likewise.
	* gas/mips/attr-gnu-4-1-mfp64.l: Likewise.
	* gas/mips/attr-gnu-4-1-mfp64.s: Likewise.
	* gas/mips/attr-gnu-4-1-mfpxx.s: Likewise.
	* gas/mips/attr-gnu-4-1-msingle-float.l: Likewise.
	* gas/mips/attr-gnu-4-1-msingle-float.s: Likewise.
	* gas/mips/attr-gnu-4-1-msoft-float.l: Likewise.
	* gas/mips/attr-gnu-4-1-msoft-float.s: Likewise.
	* gas/mips/attr-gnu-4-1.d: Likewise.
	* gas/mips/attr-gnu-4-1.s: Likewise.
	* gas/mips/attr-gnu-4-2-mdouble-float.l: Likewise.
	* gas/mips/attr-gnu-4-2-mdouble-float.s: Likewise.
	* gas/mips/attr-gnu-4-2-msoft-float.l: Likewise.
	* gas/mips/attr-gnu-4-2-msoft-float.s: Likewise.
	* gas/mips/attr-gnu-4-2.d: Likewise.
	* gas/mips/attr-gnu-4-2.s: Likewise.
	* gas/mips/attr-gnu-4-3-mhard-float.l: Likewise.
	* gas/mips/attr-gnu-4-3-mhard-float.s: Likewise.
	* gas/mips/attr-gnu-4-3.d: Likewise.
	* gas/mips/attr-gnu-4-3.s: Likewise.
	* gas/mips/attr-gnu-4-4.l: Likewise.
	* gas/mips/attr-gnu-4-4.s: Likewise.
	* gas/mips/attr-gnu-4-5-64.l: Likewise.
	* gas/mips/attr-gnu-4-5-64.s: Likewise.
	* gas/mips/attr-gnu-4-5.d: Likewise.
	* gas/mips/attr-gnu-4-5.l: Likewise.
	* gas/mips/attr-gnu-4-5.s: Likewise.
	* gas/mips/attr-gnu-4-6-64.l: Likewise.
	* gas/mips/attr-gnu-4-6-64.s: Likewise.
	* gas/mips/attr-gnu-4-6.d: Likewise.
	* gas/mips/attr-gnu-4-6.l: Likewise.
	* gas/mips/attr-gnu-4-6.s: Likewise.
	* gas/mips/attr-gnu-4-6-msingle-float.l: Likewise.
	* gas/mips/attr-gnu-4-6-msingle-float.s: Likewise.
	* gas/mips/attr-gnu-4-6-msoft-float.l: Likewise.
	* gas/mips/attr-gnu-4-6-msoft-float.s: Likewise.
	* gas/mips/attr-gnu-4-6-noodd.l: Likewise.
	* gas/mips/attr-gnu-4-6-noodd.s: Likewise.
	* gas/mips/attr-gnu-4-7-64.l: Likewise.
	* gas/mips/attr-gnu-4-7-64.s: Likewise.
	* gas/mips/attr-gnu-4-7-msingle-float.l: Likewise.
	* gas/mips/attr-gnu-4-7-msingle-float.s: Likewise.
	* gas/mips/attr-gnu-4-7-msoft-float.l: Likewise.
	* gas/mips/attr-gnu-4-7-msoft-float.s: Likewise.
	* gas/mips/attr-gnu-4-7-odd.l: Likewise.
	* gas/mips/attr-gnu-4-7-odd.s: Likewise.
	* gas/mips/attr-gnu-4-7.d: Likewise.
	* gas/mips/attr-gnu-4-7.l: Likewise.
	* gas/mips/attr-gnu-4-7.s: Likewise.
	* gas/mips/attr-none-double.d: Likewise.
	* gas/mips/attr-none-o32-fp64.d: Likewise.
	* gas/mips/attr-none-o32-fp64-nooddspreg.d
	* gas/mips/attr-none-o32-fpxx.d: Likewise.
	* gas/mips/attr-none-single-float.d: Likewise.
	* gas/mips/attr-none-soft-float.d: Likewise.
	* gas/mips/elf_arch_mips32r3.d: Likewise.
	* gas/mips/elf_arch_mips32r5.d: Likewise.
	* gas/mips/elf_arch_mips64r3.d: Likewise.
	* gas/mips/elf_arch_mips64r5.d: Likewise.
	* gas/mips/li-d.d: Likewise.
	* gas/mips/li-d.s: Likewise.
	* gas/mips/module-check-warn.l: Likewise.
	* gas/mips/module-check-warn.s: Likewise.
	* gas/mips/module-check.d: Likewise.
	* gas/mips/module-check.s: Likewise.
	* gas/mips/module-mfp32.d: Likewise.
	* gas/mips/module-mfp32.s: Likewise.
	* gas/mips/module-mfp64.d: Likewise.
	* gas/mips/module-mfp64.s: Likewise.
	* gas/mips/module-mfp64-noodd.d: Likewise.
	* gas/mips/module-mfp64-noodd.s: Likewise.
	* gas/mips/module-mfpxx.d: Likewise.
	* gas/mips/module-mfpxx.s: Likewise.
	* gas/mips/module-msingle-float.d: Likewise.
	* gas/mips/module-msingle-float.s: Likewise.
	* gas/mips/module-msoft-float.d: Likewise.
	* gas/mips/module-msoft-float.s: Likewise.
	* gas/mips/module-set-mfpxx.d: Likewise.
	* gas/mips/module-set-mfpxx.s: Likewise.
	* gas/mips/fpxx-oddfpreg.d: Likewise.
	* gas/mips/fpxx-oddfpreg.l: Likewise.
	* gas/mips/fpxx-oddfpreg.s: Likewise.
	* gas/mips/no-odd-spreg.d: Likewise.
	* gas/mips/odd-spreg.d: Likewise.
	* gas/elf/section2.e-mips: Adjust expected output.
	* gas/mips/attr-gnu-abi-fp-1.d: Likewise.
	* gas/mips/attr-gnu-abi-msa-1.d: Likewise.
	* gas/mips/call-nonpic-1.d: Likewise.
	* gas/mips/elf_arch_mips1.d: Likewise.
	* gas/mips/elf_arch_mips2.d: Likewise.
	* gas/mips/elf_arch_mips3.d: Likewise.
	* gas/mips/elf_arch_mips32.d: Likewise.
	* gas/mips/elf_arch_mips32r2.d: Likewise.
	* gas/mips/elf_arch_mips4.d: Likewise.
	* gas/mips/elf_arch_mips5.d: Likewise.
	* gas/mips/elf_arch_mips64.d: Likewise.
	* gas/mips/elf_arch_mips64r2.d: Likewise.
	* gas/mips/elf_ase_micromips-2.d: Likewise.
	* gas/mips/elf_ase_micromips.d: Likewise.
	* gas/mips/elf_ase_mips16-2.d: Likewise.
	* gas/mips/elf_ase_mips16.d: Likewise.
	* gas/mips/module-defer-warn1.d: Likewise.
	* gas/mips/module-override.d: Likewise.
	* gas/mips/n32-consec.d: Likewise.
	* gas/mips/nan-2008-1.d: Likewise.
	* gas/mips/nan-2008-2.d: Likewise.
	* gas/mips/nan-2008-3.d: Likewise.
	* gas/mips/nan-2008-4.d: Likewise.
	* gas/mips/nan-legacy-1.d: Likewise.
	* gas/mips/nan-legacy-2.d: Likewise.
	* gas/mips/nan-legacy-3.d: Likewise.
	* gas/mips/nan-legacy-4.d: Likewise.
	* gas/mips/nan-legacy-5.d: Likewise.
	* gas/mips/tmips16-e.d: Likewise.
	* gas/mips/tmips16-f.d: Likewise.
	* gas/mips/tmipsel16-e.d: Likewise.
	* gas/mips/tmipsel16-f.d: Likewise.
	* gas/testsuite/gas/mips/mips.exp: Add new tests.

ld/testsuite/

	* ld-mips-elf/abiflags-strip1-ph.d: New.
	* ld-mips-elf/abiflags-strip2-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip3-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip4-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip5-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip6-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip7-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip8-ph.d: Likewise.
	* ld-mips-elf/abiflags-strip9-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-0-n32-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-0-n64-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-0-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-06.d: Likewise.
	* ld-mips-elf/attr-gnu-4-07.d: Likewise.
	* ld-mips-elf/attr-gnu-4-08.d: Likewise.
	* ld-mips-elf/attr-gnu-4-1-n32-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-1-n64-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-1-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-16.d: Likewise.
	* ld-mips-elf/attr-gnu-4-17.d: Likewise.
	* ld-mips-elf/attr-gnu-4-18.d: Likewise.
	* ld-mips-elf/attr-gnu-4-2-n32-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-2-n64-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-2-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-26.d: Likewise.
	* ld-mips-elf/attr-gnu-4-27.d: Likewise.
	* ld-mips-elf/attr-gnu-4-28.d: Likewise.
	* ld-mips-elf/attr-gnu-4-3-n32-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-3-n64-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-3-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-36.d: Likewise.
	* ld-mips-elf/attr-gnu-4-37.d: Likewise.
	* ld-mips-elf/attr-gnu-4-38.d: Likewise.
	* ld-mips-elf/attr-gnu-4-4-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-46.d: Likewise.
	* ld-mips-elf/attr-gnu-4-47.d: Likewise.
	* ld-mips-elf/attr-gnu-4-48.d: Likewise.
	* ld-mips-elf/attr-gnu-4-5-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-50.d: Likewise.
	* ld-mips-elf/attr-gnu-4-52.d: Likewise.
	* ld-mips-elf/attr-gnu-4-53.d: Likewise.
	* ld-mips-elf/attr-gnu-4-54.d: Likewise.
	* ld-mips-elf/attr-gnu-4-55.d: Likewise.
	* ld-mips-elf/attr-gnu-4-56.d: Likewise.
	* ld-mips-elf/attr-gnu-4-57.d: Likewise.
	* ld-mips-elf/attr-gnu-4-58.d: Likewise.
	* ld-mips-elf/attr-gnu-4-6-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-6.s: Likewise.
	* ld-mips-elf/attr-gnu-4-60.d: Likewise.
	* ld-mips-elf/attr-gnu-4-61.d: Likewise.
	* ld-mips-elf/attr-gnu-4-62.d: Likewise.
	* ld-mips-elf/attr-gnu-4-63.d: Likewise.
	* ld-mips-elf/attr-gnu-4-64.d: Likewise.
	* ld-mips-elf/attr-gnu-4-65.d: Likewise.
	* ld-mips-elf/attr-gnu-4-66.d: Likewise.
	* ld-mips-elf/attr-gnu-4-67.d: Likewise.
	* ld-mips-elf/attr-gnu-4-68.d: Likewise.
	* ld-mips-elf/attr-gnu-4-7-ph.d: Likewise.
	* ld-mips-elf/attr-gnu-4-7.s: Likewise.
	* ld-mips-elf/attr-gnu-4-70.d: Likewise.
	* ld-mips-elf/attr-gnu-4-71.d: Likewise.
	* ld-mips-elf/attr-gnu-4-72.d: Likewise.
	* ld-mips-elf/attr-gnu-4-73.d: Likewise.
	* ld-mips-elf/attr-gnu-4-74.d: Likewise.
	* ld-mips-elf/attr-gnu-4-75.d: Likewise.
	* ld-mips-elf/attr-gnu-4-76.d: Likewise.
	* ld-mips-elf/attr-gnu-4-77.d: Likewise.
	* ld-mips-elf/attr-gnu-4-78.d: Likewise.
	* ld-mips-elf/attr-gnu-4-8.s: Likewise.
	* ld-mips-elf/attr-gnu-4-81.d: Likewise.
	* ld-mips-elf/empty.s: Likewise.
	* ld-mips-elf/attr-gnu-4-00.d: Adjust expected output.
	* ld-mips-elf/attr-gnu-4-01.d: Likewise.
	* ld-mips-elf/attr-gnu-4-02.d: Likewise.
	* ld-mips-elf/attr-gnu-4-03.d: Likewise.
	* ld-mips-elf/attr-gnu-4-04.d: Likewise.
	* ld-mips-elf/attr-gnu-4-05.d: Likewise.
	* ld-mips-elf/attr-gnu-4-10.d: Likewise.
	* ld-mips-elf/attr-gnu-4-11.d: Likewise.
	* ld-mips-elf/attr-gnu-4-14.d: Likewise.
	* ld-mips-elf/attr-gnu-4-15.d: Likewise.
	* ld-mips-elf/attr-gnu-4-2.s: Likewise.
	* ld-mips-elf/attr-gnu-4-20.d: Likewise.
	* ld-mips-elf/attr-gnu-4-22.d: Likewise.
	* ld-mips-elf/attr-gnu-4-24.d: Likewise.
	* ld-mips-elf/attr-gnu-4-25.d: Likewise.
	* ld-mips-elf/attr-gnu-4-3.s: Likewise.
	* ld-mips-elf/attr-gnu-4-30.d: Likewise.
	* ld-mips-elf/attr-gnu-4-33.d: Likewise.
	* ld-mips-elf/attr-gnu-4-34.d: Likewise.
	* ld-mips-elf/attr-gnu-4-35.d: Likewise.
	* ld-mips-elf/attr-gnu-4-40.d: Likewise.
	* ld-mips-elf/attr-gnu-4-41.d: Likewise.
	* ld-mips-elf/attr-gnu-4-42.d: Likewise.
	* ld-mips-elf/attr-gnu-4-43.d: Likewise.
	* ld-mips-elf/attr-gnu-4-44.d: Likewise.
	* ld-mips-elf/attr-gnu-4-45.d: Likewise.
	* ld-mips-elf/attr-gnu-4-5.s: Likewise.
	* ld-mips-elf/attr-gnu-4-51.d: Likewise.
	* ld-mips-elf/attr-gnu-8-00.d: Likewise.
	* ld-mips-elf/attr-gnu-8-01.d: Likewise.
	* ld-mips-elf/attr-gnu-8-02.d: Likewise.
	* ld-mips-elf/attr-gnu-8-10.d: Likewise.
	* ld-mips-elf/attr-gnu-8-11.d: Likewise.
	* ld-mips-elf/attr-gnu-8-20.d: Likewise.
	* ld-mips-elf/attr-gnu-8-22.d: Likewise.
	* ld-mips-elf/jalx-2.dd: Likewise.
	* ld-mips-elf/mips16-pic-1.gd: Likewise.
	* ld-mips-elf/mips16-pic-2.gd: Likewise.
	* ld-mips-elf/mips16-pic-3.gd: Likewise.
	* ld-mips-elf/mips16-pic-4a.gd: Likewise.
	* ld-mips-elf/multi-got-no-shared.d: Likewise.
	* ld-mips-elf/nan-2008.d: Likewise.
	* ld-mips-elf/nan-legacy.d: Rework test.
	* ld-mips-elf/pic-and-nonpic-3a.gd: Likewise.
	* ld-mips-elf/pic-and-nonpic-3b.gd: Likewise.
	* ld-mips-elf/pic-and-nonpic-5b.gd: Likewise.
	* ld-mips-elf/pic-and-nonpic-6.ld: Likewise.
	* ld-mips-elf/rel32-n32.d: Likewise.
	* ld-mips-elf/rel32-o32.d: Likewise.
	* ld-mips-elf/rel64.d: Likewise.
	* ld-mips-elf/tls-multi-got-1.r: Likewise.
	* ld-elf/group.ld: Discard .MIPS.abiflags and .gnu.attributes.
	* ld-elf/orphan-region.ld: Likewise.
	* ld-elf/orphan.ld: Likewise.
	* ld-mips-elf/compressed-plt-1.ld: Likewise.
	* ld-mips-elf/dyn-sec64.ld: Likewise.
	* ld-mips-elf/got-dump-1.ld: Likewise.
	* ld-mips-elf/got-dump-2.ld: Likewise.
	* ld-mips-elf/got-page-1.ld: Likewise.
	* ld-mips-elf/mips-dyn.ld: Likewise.
	* ld-mips-elf/mips-lib.ld: Likewise.
	* ld-mips-elf/pic-and-nonpic-3a.ld: Likewise.
	* ld-mips-elf/pic-and-nonpic-3b.ld: Likewise.
	* ld-mips-elf/pic-and-nonpic-4b.ld: Likewise.
	* ld-mips-elf/pic-and-nonpic-5b.ld: Likewise.
	* ld-mips-elf/region1.t: Likewise.
	* ld-mips-elf/stub-dynsym-1.ld: Likewise.
	* ld-mips-elf/tls-hidden3.ld: Likewise.
	* ld-mips-elf/vxworks1.ld: Likewise.
	* ld-scripts/overlay-size.t: Likewise.
	* ld-mips-elf/elf-rel-got-n32-embed.d: Remove .MIPS.abiflags from
	objects.
	* ld-mips-elf/elf-rel-got-n32.d: Likewise.
	* ld-mips-elf/elf-rel-got-n64-embed.d: Likewise.
	* ld-mips-elf/elf-rel-got-n64-linux.d: Likewise.
	* ld-mips-elf/elf-rel-got-n64.d: Likewise.
	* ld-mips-elf/elf-rel-xgot-n32.d: Likewise.
	* ld-mips-elf/elf-rel-xgot-n32-embed.d: Likewise.
	* ld-mips-elf/elf-rel-xgot-n64.d: Likewise.
	* ld-mips-elf/elf-rel-xgot-n64-linux.d: Likewise.
	* ld-mips-elf/elf-rel-xgot-n64-embed.d: Likewise.
	* ld-mips-elf/mips-elf.exp: Add new tests.
This commit is contained in:
Matthew Fortune 2014-07-29 11:27:59 +01:00
parent 7e09a22367
commit 351cdf24d2
314 changed files with 5204 additions and 381 deletions

View File

@ -1,3 +1,35 @@
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* elfxx-mips.c (ABI_O32_P, MIPS_ELF_ABIFLAGS_SECTION_NAME_P): New macro.
(mips_elf_obj_tdata): Add abiflags and abiflags_valid fields.
(bfd_mips_elf_swap_abiflags_v0_in): New function.
(bfd_mips_elf_swap_abiflags_v0_out): Likewise.
(_bfd_mips_elf_section_from_shdr): Handle SHT_MIPS_ABIFLAGS.
(_bfd_mips_elf_fake_sections): Likewise.
(_bfd_mips_elf_always_size_sections): Handle .MIPS.abiflags.
(_bfd_mips_elf_additional_program_headers): Account for new
PT_MIPS_ABIFLAGS program header.
(_bfd_mips_elf_modify_segment_map): Create PT_MIPS_ABIFLAGS segment and
associate with .MIPS.abiflags.
(_bfd_mips_elf_gc_mark_extra_sections): New function.
(bfd_mips_isa_ext, update_mips_abiflags_isa): New static function.
(infer_mips_abiflags): Likewise.
(_bfd_mips_elf_final_link): Handle .MIPS.abiflags.
(mips_32bit_flags_p): Moved higher.
(mips_elf_merge_obj_attributes, _bfd_mips_fp_abi_string): Error
checking for FP ABIs.
(_bfd_mips_elf_merge_private_bfd_data): Restructure and add abiflags
checks. Check EF_MIPS_FP64 flag consistency.
(print_mips_ases, print_mips_isa_ext): New static function.
(print_mips_fp_abi_value, get_mips_reg_size): Likewise.
(_bfd_mips_elf_print_private_bfd_data): Display abiflags data.
(_bfd_mips_post_process_headers): Set EI_ABIVERSION = 3 for
Val_GNU_MIPS_ABI_FP_64 or Val_GNU_MIPS_ABI_FP_64A.
* elfxx-mips.h (_bfd_mips_elf_gc_mark_extra_sections): New prototype.
* elf32-mips.c (elf_backend_gc_mark_extra_sections): Implement.
* elfn32-mips.c (elf_backend_gc_mark_extra_sections): Implement.
* elf64-mips.c (elf_backend_gc_mark_extra_sections): Implement.
2014-07-28 Alan Modra <amodra@gmail.com>
PR 13227

View File

@ -2315,6 +2315,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define elf_backend_collect TRUE
#define elf_backend_type_change_ok TRUE
#define elf_backend_can_gc_sections TRUE
#define elf_backend_gc_mark_extra_sections \
_bfd_mips_elf_gc_mark_extra_sections
#define elf_info_to_howto mips_info_to_howto_rela
#define elf_info_to_howto_rel mips_info_to_howto_rel
#define elf_backend_sym_is_global mips_elf_sym_is_global

View File

@ -4185,6 +4185,8 @@ const struct elf_size_info mips_elf64_size_info =
#define elf_backend_collect TRUE
#define elf_backend_type_change_ok TRUE
#define elf_backend_can_gc_sections TRUE
#define elf_backend_gc_mark_extra_sections \
_bfd_mips_elf_gc_mark_extra_sections
#define elf_info_to_howto mips_elf64_info_to_howto_rela
#define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
#define elf_backend_object_p mips_elf64_object_p

View File

@ -3410,6 +3410,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define elf_backend_collect TRUE
#define elf_backend_type_change_ok TRUE
#define elf_backend_can_gc_sections TRUE
#define elf_backend_gc_mark_extra_sections \
_bfd_mips_elf_gc_mark_extra_sections
#define elf_info_to_howto mips_info_to_howto_rela
#define elf_info_to_howto_rel mips_info_to_howto_rel
#define elf_backend_sym_is_global mips_elf_sym_is_global

View File

@ -547,6 +547,10 @@ struct mips_elf_obj_tdata
/* Input BFD providing Tag_GNU_MIPS_ABI_MSA attribute for output. */
bfd *abi_msa_bfd;
/* The abiflags for this object. */
Elf_Internal_ABIFlags_v0 abiflags;
bfd_boolean abiflags_valid;
/* The GOT requirements of input bfds. */
struct mips_got_info *got;
@ -776,6 +780,10 @@ static bfd *reldyn_sorting_bfd;
#define PIC_OBJECT_P(abfd) \
((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
/* Nonzero if ABFD is using the O32 ABI. */
#define ABI_O32_P(abfd) \
((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_O32)
/* Nonzero if ABFD is using the N32 ABI. */
#define ABI_N32_P(abfd) \
((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
@ -808,6 +816,10 @@ static bfd *reldyn_sorting_bfd;
#define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \
(strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)
/* True if NAME is the recognized name of any SHT_MIPS_ABIFLAGS section. */
#define MIPS_ELF_ABIFLAGS_SECTION_NAME_P(NAME) \
(strcmp (NAME, ".MIPS.abiflags") == 0)
/* Whether the section is readonly. */
#define MIPS_ELF_READONLY_SECTION(sec) \
((sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) \
@ -2664,6 +2676,46 @@ bfd_mips_elf_swap_options_out (bfd *abfd, const Elf_Internal_Options *in,
H_PUT_16 (abfd, in->section, ex->section);
H_PUT_32 (abfd, in->info, ex->info);
}
/* Swap in an abiflags structure. */
void
bfd_mips_elf_swap_abiflags_v0_in (bfd *abfd,
const Elf_External_ABIFlags_v0 *ex,
Elf_Internal_ABIFlags_v0 *in)
{
in->version = H_GET_16 (abfd, ex->version);
in->isa_level = H_GET_8 (abfd, ex->isa_level);
in->isa_rev = H_GET_8 (abfd, ex->isa_rev);
in->gpr_size = H_GET_8 (abfd, ex->gpr_size);
in->cpr1_size = H_GET_8 (abfd, ex->cpr1_size);
in->cpr2_size = H_GET_8 (abfd, ex->cpr2_size);
in->fp_abi = H_GET_8 (abfd, ex->fp_abi);
in->isa_ext = H_GET_32 (abfd, ex->isa_ext);
in->ases = H_GET_32 (abfd, ex->ases);
in->flags1 = H_GET_32 (abfd, ex->flags1);
in->flags2 = H_GET_32 (abfd, ex->flags2);
}
/* Swap out an abiflags structure. */
void
bfd_mips_elf_swap_abiflags_v0_out (bfd *abfd,
const Elf_Internal_ABIFlags_v0 *in,
Elf_External_ABIFlags_v0 *ex)
{
H_PUT_16 (abfd, in->version, ex->version);
H_PUT_8 (abfd, in->isa_level, ex->isa_level);
H_PUT_8 (abfd, in->isa_rev, ex->isa_rev);
H_PUT_8 (abfd, in->gpr_size, ex->gpr_size);
H_PUT_8 (abfd, in->cpr1_size, ex->cpr1_size);
H_PUT_8 (abfd, in->cpr2_size, ex->cpr2_size);
H_PUT_8 (abfd, in->fp_abi, ex->fp_abi);
H_PUT_32 (abfd, in->isa_ext, ex->isa_ext);
H_PUT_32 (abfd, in->ases, ex->ases);
H_PUT_32 (abfd, in->flags1, ex->flags1);
H_PUT_32 (abfd, in->flags2, ex->flags2);
}
/* This function is called via qsort() to sort the dynamic relocation
entries by increasing r_symndx value. */
@ -6910,6 +6962,11 @@ _bfd_mips_elf_section_from_shdr (bfd *abfd,
if (!MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
return FALSE;
break;
case SHT_MIPS_ABIFLAGS:
if (!MIPS_ELF_ABIFLAGS_SECTION_NAME_P (name))
return FALSE;
flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE);
break;
case SHT_MIPS_DWARF:
if (! CONST_STRNEQ (name, ".debug_")
&& ! CONST_STRNEQ (name, ".zdebug_"))
@ -6940,6 +6997,20 @@ _bfd_mips_elf_section_from_shdr (bfd *abfd,
return FALSE;
}
if (hdr->sh_type == SHT_MIPS_ABIFLAGS)
{
Elf_External_ABIFlags_v0 ext;
if (! bfd_get_section_contents (abfd, hdr->bfd_section,
&ext, 0, sizeof ext))
return FALSE;
bfd_mips_elf_swap_abiflags_v0_in (abfd, &ext,
&mips_elf_tdata (abfd)->abiflags);
if (mips_elf_tdata (abfd)->abiflags.version != 0)
return FALSE;
mips_elf_tdata (abfd)->abiflags_valid = TRUE;
}
/* FIXME: We should record sh_info for a .gptab section. */
/* For a .reginfo section, set the gp value in the tdata information
@ -7106,6 +7177,11 @@ _bfd_mips_elf_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
hdr->sh_entsize = 1;
hdr->sh_flags |= SHF_MIPS_NOSTRIP;
}
else if (CONST_STRNEQ (name, ".MIPS.abiflags"))
{
hdr->sh_type = SHT_MIPS_ABIFLAGS;
hdr->sh_entsize = sizeof (Elf_External_ABIFlags_v0);
}
else if (CONST_STRNEQ (name, ".debug_")
|| CONST_STRNEQ (name, ".zdebug_"))
{
@ -9025,7 +9101,7 @@ bfd_boolean
_bfd_mips_elf_always_size_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
asection *ri;
asection *sect;
struct mips_elf_link_hash_table *htab;
struct mips_htab_traverse_info hti;
@ -9033,9 +9109,14 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
BFD_ASSERT (htab != NULL);
/* The .reginfo section has a fixed size. */
ri = bfd_get_section_by_name (output_bfd, ".reginfo");
if (ri != NULL)
bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo));
sect = bfd_get_section_by_name (output_bfd, ".reginfo");
if (sect != NULL)
bfd_set_section_size (output_bfd, sect, sizeof (Elf32_External_RegInfo));
/* The .MIPS.abiflags section has a fixed size. */
sect = bfd_get_section_by_name (output_bfd, ".MIPS.abiflags");
if (sect != NULL)
bfd_set_section_size (output_bfd, sect, sizeof (Elf_External_ABIFlags_v0));
hti.info = info;
hti.output_bfd = output_bfd;
@ -11782,6 +11863,10 @@ _bfd_mips_elf_additional_program_headers (bfd *abfd,
if (s && (s->flags & SEC_LOAD))
++ret;
/* See if we need a PT_MIPS_ABIFLAGS segment. */
if (bfd_get_section_by_name (abfd, ".MIPS.abiflags"))
++ret;
/* See if we need a PT_MIPS_OPTIONS segment. */
if (IRIX_COMPAT (abfd) == ict_irix6
&& bfd_get_section_by_name (abfd,
@ -11844,6 +11929,37 @@ _bfd_mips_elf_modify_segment_map (bfd *abfd,
}
}
/* If there is a .MIPS.abiflags section, we need a PT_MIPS_ABIFLAGS
segment. */
s = bfd_get_section_by_name (abfd, ".MIPS.abiflags");
if (s != NULL && (s->flags & SEC_LOAD) != 0)
{
for (m = elf_seg_map (abfd); m != NULL; m = m->next)
if (m->p_type == PT_MIPS_ABIFLAGS)
break;
if (m == NULL)
{
amt = sizeof *m;
m = bfd_zalloc (abfd, amt);
if (m == NULL)
return FALSE;
m->p_type = PT_MIPS_ABIFLAGS;
m->count = 1;
m->sections[0] = s;
/* We want to put it after the PHDR and INTERP segments. */
pm = &elf_seg_map (abfd);
while (*pm != NULL
&& ((*pm)->p_type == PT_PHDR
|| (*pm)->p_type == PT_INTERP))
pm = &(*pm)->next;
m->next = *pm;
*pm = m;
}
}
/* For IRIX 6, we don't have .mdebug sections, nor does anything but
.dynamic end up in PT_DYNAMIC. However, we do have to insert a
PT_MIPS_OPTIONS segment immediately following the program header
@ -12127,6 +12243,36 @@ _bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
return TRUE;
}
/* Prevent .MIPS.abiflags from being discarded with --gc-sections. */
bfd_boolean
_bfd_mips_elf_gc_mark_extra_sections (struct bfd_link_info *info,
elf_gc_mark_hook_fn gc_mark_hook)
{
bfd *sub;
_bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *o;
if (! is_mips_elf (sub))
continue;
for (o = sub->sections; o != NULL; o = o->next)
if (!o->gc_mark
&& MIPS_ELF_ABIFLAGS_SECTION_NAME_P
(bfd_get_section_name (sub, o)))
{
if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
return FALSE;
}
}
return TRUE;
}
/* Copy data from a MIPS ELF indirect symbol to its direct symbol,
hiding the old indirect symbol. Process additional relocation
@ -13577,6 +13723,170 @@ _bfd_mips_elf_insn32 (struct bfd_link_info *info, bfd_boolean on)
mips_elf_hash_table (info)->insn32 = on;
}
/* Return the .MIPS.abiflags value representing each ISA Extension. */
unsigned int
bfd_mips_isa_ext (bfd *abfd)
{
switch (bfd_get_mach (abfd))
{
case bfd_mach_mips3900:
return AFL_EXT_3900;
case bfd_mach_mips4010:
return AFL_EXT_4010;
case bfd_mach_mips4100:
return AFL_EXT_4100;
case bfd_mach_mips4111:
return AFL_EXT_4111;
case bfd_mach_mips4120:
return AFL_EXT_4120;
case bfd_mach_mips4650:
return AFL_EXT_4650;
case bfd_mach_mips5400:
return AFL_EXT_5400;
case bfd_mach_mips5500:
return AFL_EXT_5500;
case bfd_mach_mips5900:
return AFL_EXT_5900;
case bfd_mach_mips10000:
return AFL_EXT_10000;
case bfd_mach_mips_loongson_2e:
return AFL_EXT_LOONGSON_2E;
case bfd_mach_mips_loongson_2f:
return AFL_EXT_LOONGSON_2F;
case bfd_mach_mips_loongson_3a:
return AFL_EXT_LOONGSON_3A;
case bfd_mach_mips_sb1:
return AFL_EXT_SB1;
case bfd_mach_mips_octeon:
return AFL_EXT_OCTEON;
case bfd_mach_mips_octeonp:
return AFL_EXT_OCTEONP;
case bfd_mach_mips_octeon2:
return AFL_EXT_OCTEON2;
case bfd_mach_mips_xlr:
return AFL_EXT_XLR;
}
return 0;
}
/* Update the isa_level, isa_rev, isa_ext fields of abiflags. */
static void
update_mips_abiflags_isa (bfd *abfd, Elf_Internal_ABIFlags_v0 *abiflags)
{
switch (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH)
{
case E_MIPS_ARCH_1:
abiflags->isa_level = 1;
abiflags->isa_rev = 0;
break;
case E_MIPS_ARCH_2:
abiflags->isa_level = 2;
abiflags->isa_rev = 0;
break;
case E_MIPS_ARCH_3:
abiflags->isa_level = 3;
abiflags->isa_rev = 0;
break;
case E_MIPS_ARCH_4:
abiflags->isa_level = 4;
abiflags->isa_rev = 0;
break;
case E_MIPS_ARCH_5:
abiflags->isa_level = 5;
abiflags->isa_rev = 0;
break;
case E_MIPS_ARCH_32:
abiflags->isa_level = 32;
abiflags->isa_rev = 1;
break;
case E_MIPS_ARCH_32R2:
abiflags->isa_level = 32;
/* Handle MIPS32r3 and MIPS32r5 which do not have a header flag. */
if (abiflags->isa_rev < 2)
abiflags->isa_rev = 2;
break;
case E_MIPS_ARCH_64:
abiflags->isa_level = 64;
abiflags->isa_rev = 1;
break;
case E_MIPS_ARCH_64R2:
/* Handle MIPS64r3 and MIPS64r5 which do not have a header flag. */
abiflags->isa_level = 64;
if (abiflags->isa_rev < 2)
abiflags->isa_rev = 2;
break;
default:
(*_bfd_error_handler)
(_("%B: Unknown architecture %s"),
abfd, bfd_printable_name (abfd));
}
abiflags->isa_ext = bfd_mips_isa_ext (abfd);
}
/* Return true if the given ELF header flags describe a 32-bit binary. */
static bfd_boolean
mips_32bit_flags_p (flagword flags)
{
return ((flags & EF_MIPS_32BITMODE) != 0
|| (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32
|| (flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2);
}
/* Infer the content of the ABI flags based on the elf header. */
static void
infer_mips_abiflags (bfd *abfd, Elf_Internal_ABIFlags_v0* abiflags)
{
obj_attribute *in_attr;
memset (abiflags, 0, sizeof (Elf_Internal_ABIFlags_v0));
update_mips_abiflags_isa (abfd, abiflags);
if (mips_32bit_flags_p (elf_elfheader (abfd)->e_flags))
abiflags->gpr_size = AFL_REG_32;
else
abiflags->gpr_size = AFL_REG_64;
abiflags->cpr1_size = AFL_REG_NONE;
in_attr = elf_known_obj_attributes (abfd)[OBJ_ATTR_GNU];
abiflags->fp_abi = in_attr[Tag_GNU_MIPS_ABI_FP].i;
if (abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_SINGLE
|| abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_XX
|| (abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_DOUBLE
&& abiflags->gpr_size == AFL_REG_32))
abiflags->cpr1_size = AFL_REG_32;
else if (abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_DOUBLE
|| abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_64
|| abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_64A)
abiflags->cpr1_size = AFL_REG_64;
abiflags->cpr2_size = AFL_REG_NONE;
if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MDMX)
abiflags->ases |= AFL_ASE_MDMX;
if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_M16)
abiflags->ases |= AFL_ASE_MIPS16;
if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
abiflags->ases |= AFL_ASE_MICROMIPS;
if (abiflags->fp_abi != Val_GNU_MIPS_ABI_FP_ANY
&& abiflags->fp_abi != Val_GNU_MIPS_ABI_FP_SOFT
&& abiflags->fp_abi != Val_GNU_MIPS_ABI_FP_64A
&& abiflags->isa_level >= 32
&& abiflags->isa_ext != AFL_EXT_LOONGSON_3A)
abiflags->flags1 |= AFL_FLAGS1_ODDSPREG;
}
/* We need to use a special link routine to handle the .reginfo and
the .mdebug sections. We need to merge all instances of these
sections together, not write them all out sequentially. */
@ -13587,7 +13897,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
asection *o;
struct bfd_link_order *p;
asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec;
asection *rtproc_sec;
asection *rtproc_sec, *abiflags_sec;
Elf32_RegInfo reginfo;
struct ecoff_debug_info debug;
struct mips_htab_traverse_info hti;
@ -13669,12 +13979,46 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* Go through the sections and collect the .reginfo and .mdebug
information. */
abiflags_sec = NULL;
reginfo_sec = NULL;
mdebug_sec = NULL;
gptab_data_sec = NULL;
gptab_bss_sec = NULL;
for (o = abfd->sections; o != NULL; o = o->next)
{
if (strcmp (o->name, ".MIPS.abiflags") == 0)
{
/* We have found the .MIPS.abiflags section in the output file.
Look through all the link_orders comprising it and remove them.
The data is merged in _bfd_mips_elf_merge_private_bfd_data. */
for (p = o->map_head.link_order; p != NULL; p = p->next)
{
asection *input_section;
if (p->type != bfd_indirect_link_order)
{
if (p->type == bfd_data_link_order)
continue;
abort ();
}
input_section = p->u.indirect.section;
/* Hack: reset the SEC_HAS_CONTENTS flag so that
elf_link_input_bfd ignores this section. */
input_section->flags &= ~SEC_HAS_CONTENTS;
}
/* Size has been set in _bfd_mips_elf_always_size_sections. */
BFD_ASSERT(o->size == sizeof (Elf_External_ABIFlags_v0));
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
o->map_head.link_order = NULL;
abiflags_sec = o;
}
if (strcmp (o->name, ".reginfo") == 0)
{
memset (&reginfo, 0, sizeof reginfo);
@ -14159,6 +14503,24 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* Now write out the computed sections. */
if (abiflags_sec != NULL)
{
Elf_External_ABIFlags_v0 ext;
Elf_Internal_ABIFlags_v0 *abiflags;
abiflags = &mips_elf_tdata (abfd)->abiflags;
/* Set up the abiflags if no valid input sections were found. */
if (!mips_elf_tdata (abfd)->abiflags_valid)
{
infer_mips_abiflags (abfd, abiflags);
mips_elf_tdata (abfd)->abiflags_valid = TRUE;
}
bfd_mips_elf_swap_abiflags_v0_out (abfd, abiflags, &ext);
if (! bfd_set_section_contents (abfd, abiflags_sec, &ext, 0, sizeof ext))
return FALSE;
}
if (reginfo_sec != NULL)
{
Elf32_External_RegInfo ext;
@ -14316,21 +14678,6 @@ mips_mach_extends_p (unsigned long base, unsigned long extension)
}
/* Return true if the given ELF header flags describe a 32-bit binary. */
static bfd_boolean
mips_32bit_flags_p (flagword flags)
{
return ((flags & EF_MIPS_32BITMODE) != 0
|| (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32
|| (flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2);
}
/* Merge object attributes from IBFD into OBFD. Raise an error if
there are conflicting attributes. */
static bfd_boolean
@ -14375,6 +14722,28 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
out_attr[Tag_GNU_MIPS_ABI_FP].type = 1;
if (out_fp == Val_GNU_MIPS_ABI_FP_ANY)
out_attr[Tag_GNU_MIPS_ABI_FP].i = in_fp;
else if (out_fp == Val_GNU_MIPS_ABI_FP_XX
&& (in_fp == Val_GNU_MIPS_ABI_FP_DOUBLE
|| in_fp == Val_GNU_MIPS_ABI_FP_64
|| in_fp == Val_GNU_MIPS_ABI_FP_64A))
{
mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
}
else if (in_fp == Val_GNU_MIPS_ABI_FP_XX
&& (out_fp == Val_GNU_MIPS_ABI_FP_DOUBLE
|| out_fp == Val_GNU_MIPS_ABI_FP_64
|| out_fp == Val_GNU_MIPS_ABI_FP_64A))
/* Keep the current setting. */;
else if (out_fp == Val_GNU_MIPS_ABI_FP_64A
&& in_fp == Val_GNU_MIPS_ABI_FP_64)
{
mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
}
else if (in_fp == Val_GNU_MIPS_ABI_FP_64A
&& out_fp == Val_GNU_MIPS_ABI_FP_64)
/* Keep the current setting. */;
else if (in_fp != Val_GNU_MIPS_ABI_FP_ANY)
{
const char *out_string, *in_string;
@ -14471,6 +14840,7 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
bfd_boolean ok;
bfd_boolean null_input_bfd = TRUE;
asection *sec;
obj_attribute *out_attr;
/* Check if we have the same endianness. */
if (! _bfd_generic_verify_endian_match (ibfd, obfd))
@ -14492,54 +14862,18 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
return FALSE;
}
if (!mips_elf_merge_obj_attributes (ibfd, obfd))
return FALSE;
new_flags = elf_elfheader (ibfd)->e_flags;
elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
old_flags = elf_elfheader (obfd)->e_flags;
if (! elf_flags_init (obfd))
/* Set up the FP ABI attribute from the abiflags if it is not already
set. */
if (mips_elf_tdata (ibfd)->abiflags_valid)
{
elf_flags_init (obfd) = TRUE;
elf_elfheader (obfd)->e_flags = new_flags;
elf_elfheader (obfd)->e_ident[EI_CLASS]
= elf_elfheader (ibfd)->e_ident[EI_CLASS];
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
&& (bfd_get_arch_info (obfd)->the_default
|| mips_mach_extends_p (bfd_get_mach (obfd),
bfd_get_mach (ibfd))))
{
if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
bfd_get_mach (ibfd)))
return FALSE;
}
return TRUE;
obj_attribute *in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
if (in_attr[Tag_GNU_MIPS_ABI_FP].i == Val_GNU_MIPS_ABI_FP_ANY)
in_attr[Tag_GNU_MIPS_ABI_FP].i =
mips_elf_tdata (ibfd)->abiflags.fp_abi;
}
/* Check flag compatibility. */
new_flags &= ~EF_MIPS_NOREORDER;
old_flags &= ~EF_MIPS_NOREORDER;
/* Some IRIX 6 BSD-compatibility objects have this bit set. It
doesn't seem to matter. */
new_flags &= ~EF_MIPS_XGOT;
old_flags &= ~EF_MIPS_XGOT;
/* MIPSpro generates ucode info in n64 objects. Again, we should
just be able to ignore this. */
new_flags &= ~EF_MIPS_UCODE;
old_flags &= ~EF_MIPS_UCODE;
/* DSOs should only be linked with CPIC code. */
if ((ibfd->flags & DYNAMIC) != 0)
new_flags |= EF_MIPS_PIC | EF_MIPS_CPIC;
if (new_flags == old_flags)
return TRUE;
if (!mips_elf_merge_obj_attributes (ibfd, obfd))
return FALSE;
/* Check to see if the input BFD actually contains any sections.
If not, its flags may not have been initialised either, but it cannot
@ -14565,6 +14899,130 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
if (null_input_bfd)
return TRUE;
/* Populate abiflags using existing information. */
if (!mips_elf_tdata (ibfd)->abiflags_valid)
{
infer_mips_abiflags (ibfd, &mips_elf_tdata (ibfd)->abiflags);
mips_elf_tdata (ibfd)->abiflags_valid = TRUE;
}
else
{
Elf_Internal_ABIFlags_v0 abiflags;
Elf_Internal_ABIFlags_v0 in_abiflags;
infer_mips_abiflags (ibfd, &abiflags);
in_abiflags = mips_elf_tdata (ibfd)->abiflags;
/* It is not possible to infer the correct ISA revision
for R3 or R5 so drop down to R2 for the checks. */
if (in_abiflags.isa_rev == 3 || in_abiflags.isa_rev == 5)
in_abiflags.isa_rev = 2;
if (in_abiflags.isa_level != abiflags.isa_level
|| in_abiflags.isa_rev != abiflags.isa_rev
|| in_abiflags.isa_ext != abiflags.isa_ext)
(*_bfd_error_handler)
(_("%B: warning: Inconsistent ISA between e_flags and "
".MIPS.abiflags"), ibfd);
if (abiflags.fp_abi != Val_GNU_MIPS_ABI_FP_ANY
&& in_abiflags.fp_abi != abiflags.fp_abi)
(*_bfd_error_handler)
(_("%B: warning: Inconsistent FP ABI between e_flags and "
".MIPS.abiflags"), ibfd);
if ((in_abiflags.ases & abiflags.ases) != abiflags.ases)
(*_bfd_error_handler)
(_("%B: warning: Inconsistent ASEs between e_flags and "
".MIPS.abiflags"), ibfd);
if (in_abiflags.isa_ext != abiflags.isa_ext)
(*_bfd_error_handler)
(_("%B: warning: Inconsistent ISA extensions between e_flags and "
".MIPS.abiflags"), ibfd);
if (in_abiflags.flags2 != 0)
(*_bfd_error_handler)
(_("%B: warning: Unexpected flag in the flags2 field of "
".MIPS.abiflags (0x%lx)"), ibfd,
(unsigned long) in_abiflags.flags2);
}
if (!mips_elf_tdata (obfd)->abiflags_valid)
{
/* Copy input abiflags if output abiflags are not already valid. */
mips_elf_tdata (obfd)->abiflags = mips_elf_tdata (ibfd)->abiflags;
mips_elf_tdata (obfd)->abiflags_valid = TRUE;
}
if (! elf_flags_init (obfd))
{
elf_flags_init (obfd) = TRUE;
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
elf_elfheader (obfd)->e_ident[EI_CLASS]
= elf_elfheader (ibfd)->e_ident[EI_CLASS];
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
&& (bfd_get_arch_info (obfd)->the_default
|| mips_mach_extends_p (bfd_get_mach (obfd),
bfd_get_mach (ibfd))))
{
if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
bfd_get_mach (ibfd)))
return FALSE;
/* Update the ABI flags isa_level, isa_rev and isa_ext fields. */
update_mips_abiflags_isa (obfd, &mips_elf_tdata (obfd)->abiflags);
}
return TRUE;
}
/* Update the output abiflags fp_abi using the computed fp_abi. */
out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
mips_elf_tdata (obfd)->abiflags.fp_abi = out_attr[Tag_GNU_MIPS_ABI_FP].i;
#define max(a,b) ((a) > (b) ? (a) : (b))
/* Merge abiflags. */
mips_elf_tdata (obfd)->abiflags.isa_rev
= max (mips_elf_tdata (obfd)->abiflags.isa_rev,
mips_elf_tdata (ibfd)->abiflags.isa_rev);
mips_elf_tdata (obfd)->abiflags.gpr_size
= max (mips_elf_tdata (obfd)->abiflags.gpr_size,
mips_elf_tdata (ibfd)->abiflags.gpr_size);
mips_elf_tdata (obfd)->abiflags.cpr1_size
= max (mips_elf_tdata (obfd)->abiflags.cpr1_size,
mips_elf_tdata (ibfd)->abiflags.cpr1_size);
mips_elf_tdata (obfd)->abiflags.cpr2_size
= max (mips_elf_tdata (obfd)->abiflags.cpr2_size,
mips_elf_tdata (ibfd)->abiflags.cpr2_size);
#undef max
mips_elf_tdata (obfd)->abiflags.ases
|= mips_elf_tdata (ibfd)->abiflags.ases;
mips_elf_tdata (obfd)->abiflags.flags1
|= mips_elf_tdata (ibfd)->abiflags.flags1;
new_flags = elf_elfheader (ibfd)->e_flags;
elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
old_flags = elf_elfheader (obfd)->e_flags;
/* Check flag compatibility. */
new_flags &= ~EF_MIPS_NOREORDER;
old_flags &= ~EF_MIPS_NOREORDER;
/* Some IRIX 6 BSD-compatibility objects have this bit set. It
doesn't seem to matter. */
new_flags &= ~EF_MIPS_XGOT;
old_flags &= ~EF_MIPS_XGOT;
/* MIPSpro generates ucode info in n64 objects. Again, we should
just be able to ignore this. */
new_flags &= ~EF_MIPS_UCODE;
old_flags &= ~EF_MIPS_UCODE;
/* DSOs should only be linked with CPIC code. */
if ((ibfd->flags & DYNAMIC) != 0)
new_flags |= EF_MIPS_PIC | EF_MIPS_CPIC;
if (new_flags == old_flags)
return TRUE;
ok = TRUE;
if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)
@ -14605,6 +15063,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
elf_elfheader (obfd)->e_flags
|= new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
/* Update the ABI flags isa_level, isa_rev, isa_ext fields. */
update_mips_abiflags_isa (obfd, &mips_elf_tdata (obfd)->abiflags);
/* Copy across the ABI flags if OBFD doesn't use them
and if that was what caused us to treat IBFD as 32-bit. */
if ((old_flags & EF_MIPS_ABI) == 0
@ -14690,6 +15151,20 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
old_flags &= ~EF_MIPS_NAN2008;
}
/* Compare FP64 state. */
if ((new_flags & EF_MIPS_FP64) != (old_flags & EF_MIPS_FP64))
{
_bfd_error_handler (_("%B: linking %s module with previous %s modules"),
ibfd,
(new_flags & EF_MIPS_FP64
? "-mfp64" : "-mfp32"),
(old_flags & EF_MIPS_FP64
? "-mfp64" : "-mfp32"));
ok = FALSE;
new_flags &= ~EF_MIPS_FP64;
old_flags &= ~EF_MIPS_FP64;
}
/* Warn about any other mismatches */
if (new_flags != old_flags)
{
@ -14840,14 +15315,169 @@ _bfd_mips_fp_abi_string (int fp)
case Val_GNU_MIPS_ABI_FP_SOFT:
return "-msoft-float";
case Val_GNU_MIPS_ABI_FP_OLD_64:
return _("-mips32r2 -mfp64 (12 callee-saved)");
case Val_GNU_MIPS_ABI_FP_XX:
return "-mfpxx";
case Val_GNU_MIPS_ABI_FP_64:
return "-mips32r2 -mfp64";
return "-mgp32 -mfp64";
case Val_GNU_MIPS_ABI_FP_64A:
return "-mgp32 -mfp64 -mno-odd-spreg";
default:
return 0;
}
}
static void
print_mips_ases (FILE *file, unsigned int mask)
{
if (mask & AFL_ASE_DSP)
fputs ("\n\tDSP ASE", file);
if (mask & AFL_ASE_DSPR2)
fputs ("\n\tDSP R2 ASE", file);
if (mask & AFL_ASE_EVA)
fputs ("\n\tEnhanced VA Scheme", file);
if (mask & AFL_ASE_MCU)
fputs ("\n\tMCU (MicroController) ASE", file);
if (mask & AFL_ASE_MDMX)
fputs ("\n\tMDMX ASE", file);
if (mask & AFL_ASE_MIPS3D)
fputs ("\n\tMIPS-3D ASE", file);
if (mask & AFL_ASE_MT)
fputs ("\n\tMT ASE", file);
if (mask & AFL_ASE_SMARTMIPS)
fputs ("\n\tSmartMIPS ASE", file);
if (mask & AFL_ASE_VIRT)
fputs ("\n\tVZ ASE", file);
if (mask & AFL_ASE_MSA)
fputs ("\n\tMSA ASE", file);
if (mask & AFL_ASE_MIPS16)
fputs ("\n\tMIPS16 ASE", file);
if (mask & AFL_ASE_MICROMIPS)
fputs ("\n\tMICROMIPS ASE", file);
if (mask & AFL_ASE_XPA)
fputs ("\n\tXPA ASE", file);
if (mask == 0)
fprintf (file, "\n\t%s", _("None"));
}
static void
print_mips_isa_ext (FILE *file, unsigned int isa_ext)
{
switch (isa_ext)
{
case 0:
fputs (_("None"), file);
break;
case AFL_EXT_XLR:
fputs ("RMI XLR", file);
break;
case AFL_EXT_OCTEON2:
fputs ("Cavium Networks Octeon2", file);
break;
case AFL_EXT_OCTEONP:
fputs ("Cavium Networks OcteonP", file);
break;
case AFL_EXT_LOONGSON_3A:
fputs ("Loongson 3A", file);
break;
case AFL_EXT_OCTEON:
fputs ("Cavium Networks Octeon", file);
break;
case AFL_EXT_5900:
fputs ("Toshiba R5900", file);
break;
case AFL_EXT_4650:
fputs ("MIPS R4650", file);
break;
case AFL_EXT_4010:
fputs ("LSI R4010", file);
break;
case AFL_EXT_4100:
fputs ("NEC VR4100", file);
break;
case AFL_EXT_3900:
fputs ("Toshiba R3900", file);
break;
case AFL_EXT_10000:
fputs ("MIPS R10000", file);
break;
case AFL_EXT_SB1:
fputs ("Broadcom SB-1", file);
break;
case AFL_EXT_4111:
fputs ("NEC VR4111/VR4181", file);
break;
case AFL_EXT_4120:
fputs ("NEC VR4120", file);
break;
case AFL_EXT_5400:
fputs ("NEC VR5400", file);
break;
case AFL_EXT_5500:
fputs ("NEC VR5500", file);
break;
case AFL_EXT_LOONGSON_2E:
fputs ("ST Microelectronics Loongson 2E", file);
break;
case AFL_EXT_LOONGSON_2F:
fputs ("ST Microelectronics Loongson 2F", file);
break;
default:
fputs (_("Unknown"), file);
break;
}
}
static void
print_mips_fp_abi_value (FILE *file, int val)
{
switch (val)
{
case Val_GNU_MIPS_ABI_FP_ANY:
fprintf (file, _("Hard or soft float\n"));
break;
case Val_GNU_MIPS_ABI_FP_DOUBLE:
fprintf (file, _("Hard float (double precision)\n"));
break;
case Val_GNU_MIPS_ABI_FP_SINGLE:
fprintf (file, _("Hard float (single precision)\n"));
break;
case Val_GNU_MIPS_ABI_FP_SOFT:
fprintf (file, _("Soft float\n"));
break;
case Val_GNU_MIPS_ABI_FP_OLD_64:
fprintf (file, _("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
break;
case Val_GNU_MIPS_ABI_FP_XX:
fprintf (file, _("Hard float (32-bit CPU, Any FPU)\n"));
break;
case Val_GNU_MIPS_ABI_FP_64:
fprintf (file, _("Hard float (32-bit CPU, 64-bit FPU)\n"));
break;
case Val_GNU_MIPS_ABI_FP_64A:
fprintf (file, _("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
break;
default:
fprintf (file, "??? (%d)\n", val);
break;
}
}
static int
get_mips_reg_size (int reg_size)
{
return (reg_size == AFL_REG_NONE) ? 0
: (reg_size == AFL_REG_32) ? 32
: (reg_size == AFL_REG_64) ? 64
: (reg_size == AFL_REG_128) ? 128
: -1;
}
bfd_boolean
_bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
{
@ -14912,7 +15542,7 @@ _bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
fprintf (file, " [nan2008]");
if (elf_elfheader (abfd)->e_flags & EF_MIPS_FP64)
fprintf (file, " [fp64]");
fprintf (file, " [old fp64]");
if (elf_elfheader (abfd)->e_flags & EF_MIPS_32BITMODE)
fprintf (file, " [32bitmode]");
@ -14936,6 +15566,30 @@ _bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
fputc ('\n', file);
if (mips_elf_tdata (abfd)->abiflags_valid)
{
Elf_Internal_ABIFlags_v0 *abiflags = &mips_elf_tdata (abfd)->abiflags;
fprintf (file, "\nMIPS ABI Flags Version: %d\n", abiflags->version);
fprintf (file, "\nISA: MIPS%d", abiflags->isa_level);
if (abiflags->isa_rev > 1)
fprintf (file, "r%d", abiflags->isa_rev);
fprintf (file, "\nGPR size: %d",
get_mips_reg_size (abiflags->gpr_size));
fprintf (file, "\nCPR1 size: %d",
get_mips_reg_size (abiflags->cpr1_size));
fprintf (file, "\nCPR2 size: %d",
get_mips_reg_size (abiflags->cpr2_size));
fputs ("\nFP ABI: ", file);
print_mips_fp_abi_value (file, abiflags->fp_abi);
fputs ("ISA Extension: ", file);
print_mips_isa_ext (file, abiflags->isa_ext);
fputs ("\nASEs:", file);
print_mips_ases (file, abiflags->ases);
fprintf (file, "\nFLAGS 1: %8.8lx", abiflags->flags1);
fprintf (file, "\nFLAGS 2: %8.8lx", abiflags->flags2);
fputc ('\n', file);
}
return TRUE;
}
@ -15258,4 +15912,8 @@ _bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
}
_bfd_elf_post_process_headers (abfd, link_info);
if (mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64
|| mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64A)
i_ehdrp->e_ident[EI_ABIVERSION] = 3;
}

View File

@ -157,6 +157,8 @@ extern bfd_vma _bfd_mips_elf_plt_sym_val
(bfd_vma, const asection *, const arelent *rel);
extern long _bfd_mips_elf_get_synthetic_symtab
(bfd *, long, asymbol **, long, asymbol **, asymbol **);
extern bfd_boolean _bfd_mips_elf_gc_mark_extra_sections
(struct bfd_link_info *, elf_gc_mark_hook_fn);
extern void _bfd_mips_post_process_headers
(bfd *abfd, struct bfd_link_info *link_info);

View File

@ -1,3 +1,13 @@
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* readelf.c (get_mips_segment_type): Display name for PT_MIPS_ABIFLAGS.
(get_mips_section_type_name): Display name for SHT_MIPS_ABIFLAGS.
(display_mips_gnu_attribute): Abstracted fp abi printing to...
(print_mips_fp_abi_value): New static function. Handle new FP ABIs.
(print_mips_ases, print_mips_isa_ext): New static functions.
(get_mips_reg_size): Likewise.
(process_mips_specific): Display abiflags data.
2014-07-28 Alan Modra <amodra@gmail.com>
PR 13227

View File

@ -3167,6 +3167,8 @@ get_mips_segment_type (unsigned long type)
return "RTPROC";
case PT_MIPS_OPTIONS:
return "OPTIONS";
case PT_MIPS_ABIFLAGS:
return "ABIFLAGS";
default:
break;
}
@ -3366,6 +3368,7 @@ get_mips_section_type_name (unsigned int sh_type)
case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
default:
break;
}
@ -11990,6 +11993,41 @@ display_sparc_gnu_attribute (unsigned char * p,
return display_tag_value (tag, p, end);
}
static void
print_mips_fp_abi_value (int val)
{
switch (val)
{
case Val_GNU_MIPS_ABI_FP_ANY:
printf (_("Hard or soft float\n"));
break;
case Val_GNU_MIPS_ABI_FP_DOUBLE:
printf (_("Hard float (double precision)\n"));
break;
case Val_GNU_MIPS_ABI_FP_SINGLE:
printf (_("Hard float (single precision)\n"));
break;
case Val_GNU_MIPS_ABI_FP_SOFT:
printf (_("Soft float\n"));
break;
case Val_GNU_MIPS_ABI_FP_OLD_64:
printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
break;
case Val_GNU_MIPS_ABI_FP_XX:
printf (_("Hard float (32-bit CPU, Any FPU)\n"));
break;
case Val_GNU_MIPS_ABI_FP_64:
printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
break;
case Val_GNU_MIPS_ABI_FP_64A:
printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
break;
default:
printf ("??? (%d)\n", val);
break;
}
}
static unsigned char *
display_mips_gnu_attribute (unsigned char * p,
int tag,
@ -12004,27 +12042,8 @@ display_mips_gnu_attribute (unsigned char * p,
p += len;
printf (" Tag_GNU_MIPS_ABI_FP: ");
switch (val)
{
case Val_GNU_MIPS_ABI_FP_ANY:
printf (_("Hard or soft float\n"));
break;
case Val_GNU_MIPS_ABI_FP_DOUBLE:
printf (_("Hard float (double precision)\n"));
break;
case Val_GNU_MIPS_ABI_FP_SINGLE:
printf (_("Hard float (single precision)\n"));
break;
case Val_GNU_MIPS_ABI_FP_SOFT:
printf (_("Soft float\n"));
break;
case Val_GNU_MIPS_ABI_FP_64:
printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
break;
default:
printf ("??? (%d)\n", val);
break;
}
print_mips_fp_abi_value (val);
return p;
}
@ -12627,10 +12646,121 @@ print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
return addr + (is_32bit_elf ? 4 : 8);
}
static void
print_mips_ases (unsigned int mask)
{
if (mask & AFL_ASE_DSP)
fputs ("\n\tDSP ASE", stdout);
if (mask & AFL_ASE_DSPR2)
fputs ("\n\tDSP R2 ASE", stdout);
if (mask & AFL_ASE_EVA)
fputs ("\n\tEnhanced VA Scheme", stdout);
if (mask & AFL_ASE_MCU)
fputs ("\n\tMCU (MicroController) ASE", stdout);
if (mask & AFL_ASE_MDMX)
fputs ("\n\tMDMX ASE", stdout);
if (mask & AFL_ASE_MIPS3D)
fputs ("\n\tMIPS-3D ASE", stdout);
if (mask & AFL_ASE_MT)
fputs ("\n\tMT ASE", stdout);
if (mask & AFL_ASE_SMARTMIPS)
fputs ("\n\tSmartMIPS ASE", stdout);
if (mask & AFL_ASE_VIRT)
fputs ("\n\tVZ ASE", stdout);
if (mask & AFL_ASE_MSA)
fputs ("\n\tMSA ASE", stdout);
if (mask & AFL_ASE_MIPS16)
fputs ("\n\tMIPS16 ASE", stdout);
if (mask & AFL_ASE_MICROMIPS)
fputs ("\n\tMICROMIPS ASE", stdout);
if (mask & AFL_ASE_XPA)
fputs ("\n\tXPA ASE", stdout);
if (mask == 0)
fprintf (stdout, "\n\t%s", _("None"));
}
static void
print_mips_isa_ext (unsigned int isa_ext)
{
switch (isa_ext)
{
case 0:
fputs (_("None"), stdout);
break;
case AFL_EXT_XLR:
fputs ("RMI XLR", stdout);
break;
case AFL_EXT_OCTEON2:
fputs ("Cavium Networks Octeon2", stdout);
break;
case AFL_EXT_OCTEONP:
fputs ("Cavium Networks OcteonP", stdout);
break;
case AFL_EXT_LOONGSON_3A:
fputs ("Loongson 3A", stdout);
break;
case AFL_EXT_OCTEON:
fputs ("Cavium Networks Octeon", stdout);
break;
case AFL_EXT_5900:
fputs ("Toshiba R5900", stdout);
break;
case AFL_EXT_4650:
fputs ("MIPS R4650", stdout);
break;
case AFL_EXT_4010:
fputs ("LSI R4010", stdout);
break;
case AFL_EXT_4100:
fputs ("NEC VR4100", stdout);
break;
case AFL_EXT_3900:
fputs ("Toshiba R3900", stdout);
break;
case AFL_EXT_10000:
fputs ("MIPS R10000", stdout);
break;
case AFL_EXT_SB1:
fputs ("Broadcom SB-1", stdout);
break;
case AFL_EXT_4111:
fputs ("NEC VR4111/VR4181", stdout);
break;
case AFL_EXT_4120:
fputs ("NEC VR4120", stdout);
break;
case AFL_EXT_5400:
fputs ("NEC VR5400", stdout);
break;
case AFL_EXT_5500:
fputs ("NEC VR5500", stdout);
break;
case AFL_EXT_LOONGSON_2E:
fputs ("ST Microelectronics Loongson 2E", stdout);
break;
case AFL_EXT_LOONGSON_2F:
fputs ("ST Microelectronics Loongson 2F", stdout);
break;
default:
fputs (_("Unknown"), stdout);
}
}
static int
get_mips_reg_size (int reg_size)
{
return (reg_size == AFL_REG_NONE) ? 0
: (reg_size == AFL_REG_32) ? 32
: (reg_size == AFL_REG_64) ? 64
: (reg_size == AFL_REG_128) ? 128
: -1;
}
static int
process_mips_specific (FILE * file)
{
Elf_Internal_Dyn * entry;
Elf_Internal_Shdr *sect = NULL;
size_t liblist_offset = 0;
size_t liblistno = 0;
size_t conflictsno = 0;
@ -12648,6 +12778,57 @@ process_mips_specific (FILE * file)
process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
display_mips_gnu_attribute);
sect = find_section (".MIPS.abiflags");
if (sect != NULL)
{
Elf_External_ABIFlags_v0 *abiflags_ext;
Elf_Internal_ABIFlags_v0 abiflags_in;
if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
fputs ("\nCorrupt ABI Flags section.\n", stdout);
else
{
abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
sect->sh_size, _("MIPS ABI Flags section"));
if (abiflags_ext)
{
abiflags_in.version = BYTE_GET (abiflags_ext->version);
abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
printf ("\nISA: MIPS%d", abiflags_in.isa_level);
if (abiflags_in.isa_rev > 1)
printf ("r%d", abiflags_in.isa_rev);
printf ("\nGPR size: %d",
get_mips_reg_size (abiflags_in.gpr_size));
printf ("\nCPR1 size: %d",
get_mips_reg_size (abiflags_in.cpr1_size));
printf ("\nCPR2 size: %d",
get_mips_reg_size (abiflags_in.cpr2_size));
fputs ("\nFP ABI: ", stdout);
print_mips_fp_abi_value (abiflags_in.fp_abi);
fputs ("ISA Extension: ", stdout);
print_mips_isa_ext (abiflags_in.isa_ext);
fputs ("\nASEs:", stdout);
print_mips_ases (abiflags_in.ases);
printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
fputc ('\n', stdout);
free (abiflags_ext);
}
}
}
/* We have a lot of special sections. Thanks SGI! */
if (dynamic_section == NULL)
/* No information available. */
@ -12787,11 +12968,11 @@ process_mips_specific (FILE * file)
if (options_offset != 0)
{
Elf_External_Options * eopt;
Elf_Internal_Shdr * sect = section_headers;
Elf_Internal_Options * iopt;
Elf_Internal_Options * option;
size_t offset;
int cnt;
sect = section_headers;
/* Find the section header so that we get the size. */
while (sect->sh_type != SHT_MIPS_OPTIONS)

View File

@ -1,3 +1,10 @@
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* binutils-all/readelf.s: Account for .MIPS.abiflags and
.gnu.attributes.
* binutils-all/readelf.ss-tmips: Likewise.
* binutils-all/strip-3.d: Likewise.
2014-07-10 Will Newton <will.newton@linaro.org>
* binutils-all/objcopy.exp: Disable the strip-10 test on

View File

@ -6,16 +6,16 @@ Section Headers:
# On the normal MIPS systems, sections must be aligned to 16 byte
# boundaries. On IA64, text sections are aligned to 16 byte boundaries.
+\[ 1\] .text +PROGBITS +00000000 0000(34|40) 0000(08|10) 00 +AX +0 +0 +(.|..)
+\[ 2\] .rel.+text +REL. +0+ 0+.* 0000.. 0. +I +. +1 +4
+\[ 2\] .rel.+text +REL. +0+ 0+.* 0000.. 0. +I +.+ +1 +4
# MIPS targets put .rela.text here.
#...
+\[ .\] .data +PROGBITS +00000000 0000(3c|48|50) 0000(04|10) 00 +WA +0 +0 +(.|..)
+\[ .\] .bss +NOBITS +00000000 0000(40|4c|60) 000000 00 +WA +0 +0 +(.|..)
# MIPS targets put .reginfo and .mdebug here.
# MIPS targets put .reginfo, .mdebug, .MIPS.abiflags and .gnu.attributes here.
# v850 targets put .call_table_data and .call_table_text here.
#...
+\[ .\] .shstrtab +STRTAB +00000000 0+.* 0+.* 00 +0 +0 +.
+\[ .\] .symtab +SYMTAB +00000000 0+.* 0+.* 10 +.. +. +4
+\[..\] .symtab +SYMTAB +00000000 0+.* 0+.* 10 +.. +.+ +4
+\[..\] .strtab +STRTAB +00000000 0+.* 0+.* 00 +0 +0 +1
Key to Flags:
#...

View File

@ -1,5 +1,5 @@
Symbol table '.symtab' contains 12 entries:
Symbol table '.symtab' contains 14 entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+0: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +UND
+1: 00000000 +0 +SECTION +LOCAL +DEFAULT +1
@ -9,7 +9,9 @@ Symbol table '.symtab' contains 12 entries:
+5: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
+6: 00000000 +0 +SECTION +LOCAL +DEFAULT +5
+7: 00000000 +0 +SECTION +LOCAL +DEFAULT +6
+8: 00000000 +0 +OBJECT +GLOBAL +DEFAULT +1 text_symbol
+9: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
+10: 00000000 +0 +OBJECT +GLOBAL +DEFAULT +3 data_symbol
+11: 00000004 +4 +(COMMON|OBJECT) +GLOBAL +DEFAULT +(PRC|COM) common_symbol
+8: 00000000 +0 +SECTION +LOCAL +DEFAULT +7
+9: 00000000 +0 +SECTION +LOCAL +DEFAULT +8
+10: 00000000 +0 +OBJECT +GLOBAL +DEFAULT +1 text_symbol
+11: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
+12: 00000000 +0 +OBJECT +GLOBAL +DEFAULT +3 data_symbol
+13: 00000004 +4 +(COMMON|OBJECT) +GLOBAL +DEFAULT +(PRC|COM) common_symbol

View File

@ -1,6 +1,6 @@
#PROG: strip
#source: empty.s
#strip: -R .text -R .data -R .bss -R .ARM.attributes -R .reginfo -R .pdr -R .xtensa.info
#strip: -R .text -R .data -R .bss -R .ARM.attributes -R .reginfo -R .gnu.attributes -R .MIPS.abiflags -R .pdr -R .xtensa.info
#readelf: -S --wide
#name: strip empty file
#target: *-*-linux* *-*-gnu*

View File

@ -1,3 +1,7 @@
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* elfcpp.h (PT_MIPS_ABIFLAGS): New program header type.
2014-07-02 Jing Yu <jingyu@google.com>
* aarch64.h: New file. New enums for aarch64-elf64 relocations.

View File

@ -495,6 +495,8 @@ enum PT
PT_MIPS_RTPROC = 0x70000001,
// .MIPS.options section.
PT_MIPS_OPTIONS = 0x70000002,
// .MIPS.abiflags section.
PT_MIPS_ABIFLAGS = 0x70000003,
// Platform architecture compatibility information
PT_AARCH64_ARCHEXT = 0x70000000,
// Exception unwind tables

View File

@ -1,3 +1,40 @@
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* config/tc-mips.c (mips_flags_frag): New static global.
(struct mips_set_options): Add oddspreg field.
(file_mips_opts, mips_opts): Initialize oddspreg.
(ISA_HAS_ODD_SINGLE_FPR): Add CPU argument and update for R5900 and
Loongson-3a.
(enum options, md_longopts, md_parse_option): Add -mfpxx, -modd-spreg
and -mno-odd-spreg options.
(md_begin): Create .MIPS.abiflags section.
(fpabi_incompatible_with, fpabi_requires): New static function.
(check_fpabi): Likewise.
(mips_check_options): Handle fp=xx and oddspreg restrictions.
(file_mips_check_options): Set oddspreg by default for fp=xx.
(mips_oddfpreg_ok): Re-write function.
(check_regno): Check odd numbered registers regardless of FPR size.
For fp != 32 use as_bad instead of as_warn.
(match_float_constant): Rewrite check regarding FP register width. Add
support for generating constants when MXHC1 is present. Handle fp=xx
to comply with the ABI.
(macro): Update M_LI_DD similarly to match_float_constant. Generate
MTHC1 when available. Check that correct code can be generated for
fp=xx and fp=64 ABIs.
(parse_code_option, s_mipsset): Add fp=xx, oddspreg and nooddspreg
options.
(mips_convert_ase_flags): New static function.
(mips_elf_final_processing): Use fpabi == Val_GNU_MIPS_ABI_FP_OLD_64
to determine when to add the EF_MIPS_FP64 flag. Populate the
.MIPS.abiflags section.
(md_mips_end): Update .gnu_attribute based on command line and .module
as applicable. Use check_fpabi to ensure .gnu.attribute and command
line/.module options are consistent.
* doc/as.texinfo: Add missing -mgp64/-mfp64 options and document new
-mfpxx, -modd-spreg and -mno-odd-spreg options.
* doc/c-mips.texi: Document -mfpxx, -modd-spreg, -mno-odd-spreg,
gnu_attribute values and FP ABIs.
2014-07-27 Joel Sherrill <joel.sherrill@oarcorp.com>
Add RTEMS target support and simplify matching

View File

@ -89,6 +89,7 @@ int mips_flag_pdr = TRUE;
#include "ecoff.h"
static char *mips_regmask_frag;
static char *mips_flags_frag;
#define ZERO 0
#define ATREG 1
@ -257,6 +258,10 @@ struct mips_set_options
Changed by .set singlefloat or .set doublefloat, command-line options
-msingle-float or -mdouble-float. The default is false. */
bfd_boolean single_float;
/* 1 if single-precision operations on odd-numbered registers are
allowed. */
int oddspreg;
};
/* Specifies whether module level options have been checked yet. */
@ -275,7 +280,7 @@ static struct mips_set_options file_mips_opts =
/* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
/* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* insn32 */ FALSE,
/* gp */ -1, /* fp */ -1, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
/* soft_float */ FALSE, /* single_float */ FALSE
/* soft_float */ FALSE, /* single_float */ FALSE, /* oddspreg */ -1
};
/* This is similar to file_mips_opts, but for the current set of options. */
@ -286,7 +291,7 @@ static struct mips_set_options mips_opts =
/* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
/* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* insn32 */ FALSE,
/* gp */ -1, /* fp */ -1, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
/* soft_float */ FALSE, /* single_float */ FALSE
/* soft_float */ FALSE, /* single_float */ FALSE, /* oddspreg */ -1
};
/* Which bits of file_ase were explicitly set or cleared by ASE options. */
@ -392,15 +397,17 @@ static int mips_32bitmode = 0;
)
/* Return true if ISA supports single-precision floats in odd registers. */
#define ISA_HAS_ODD_SINGLE_FPR(ISA) \
((ISA) == ISA_MIPS32 \
|| (ISA) == ISA_MIPS32R2 \
|| (ISA) == ISA_MIPS32R3 \
|| (ISA) == ISA_MIPS32R5 \
|| (ISA) == ISA_MIPS64 \
|| (ISA) == ISA_MIPS64R2 \
|| (ISA) == ISA_MIPS64R3 \
|| (ISA) == ISA_MIPS64R5)
#define ISA_HAS_ODD_SINGLE_FPR(ISA, CPU)\
(((ISA) == ISA_MIPS32 \
|| (ISA) == ISA_MIPS32R2 \
|| (ISA) == ISA_MIPS32R3 \
|| (ISA) == ISA_MIPS32R5 \
|| (ISA) == ISA_MIPS64 \
|| (ISA) == ISA_MIPS64R2 \
|| (ISA) == ISA_MIPS64R3 \
|| (ISA) == ISA_MIPS64R5 \
|| (CPU) == CPU_R5900) \
&& (CPU) != CPU_LOONGSON_3A)
/* Return true if ISA supports move to/from high part of a 64-bit
floating-point register. */
@ -1407,6 +1414,7 @@ enum options
OPTION_CONSTRUCT_FLOATS,
OPTION_NO_CONSTRUCT_FLOATS,
OPTION_FP64,
OPTION_FPXX,
OPTION_GP64,
OPTION_RELAX_BRANCH,
OPTION_NO_RELAX_BRANCH,
@ -1434,6 +1442,8 @@ enum options
OPTION_NO_PDR,
OPTION_MVXWORKS_PIC,
OPTION_NAN,
OPTION_ODD_SPREG,
OPTION_NO_ODD_SPREG,
OPTION_END_OF_ENUM
};
@ -1526,6 +1536,7 @@ struct option md_longopts[] =
{"construct-floats", no_argument, NULL, OPTION_CONSTRUCT_FLOATS},
{"no-construct-floats", no_argument, NULL, OPTION_NO_CONSTRUCT_FLOATS},
{"mfp64", no_argument, NULL, OPTION_FP64},
{"mfpxx", no_argument, NULL, OPTION_FPXX},
{"mgp64", no_argument, NULL, OPTION_GP64},
{"relax-branch", no_argument, NULL, OPTION_RELAX_BRANCH},
{"no-relax-branch", no_argument, NULL, OPTION_NO_RELAX_BRANCH},
@ -1539,6 +1550,8 @@ struct option md_longopts[] =
{"mhard-float", no_argument, NULL, OPTION_HARD_FLOAT},
{"msingle-float", no_argument, NULL, OPTION_SINGLE_FLOAT},
{"mdouble-float", no_argument, NULL, OPTION_DOUBLE_FLOAT},
{"modd-spreg", no_argument, NULL, OPTION_ODD_SPREG},
{"mno-odd-spreg", no_argument, NULL, OPTION_NO_ODD_SPREG},
/* Strictly speaking this next option is ELF specific,
but we allow it for other ports as well in order to
@ -3612,6 +3625,12 @@ md_begin (void)
}
}
sec = subseg_new (".MIPS.abiflags", (subsegT) 0);
bfd_set_section_flags (stdoutput, sec,
SEC_READONLY | SEC_DATA | SEC_ALLOC | SEC_LOAD);
bfd_set_section_alignment (stdoutput, sec, 3);
mips_flags_frag = frag_more (sizeof (Elf_External_ABIFlags_v0));
if (ECOFF_DEBUGGING)
{
sec = subseg_new (".mdebug", (subsegT) 0);
@ -3635,6 +3654,88 @@ md_begin (void)
init_vr4120_conflicts ();
}
static inline void
fpabi_incompatible_with (int fpabi, const char *what)
{
as_warn (_(".gnu_attribute %d,%d is incompatible with `%s'"),
Tag_GNU_MIPS_ABI_FP, fpabi, what);
}
static inline void
fpabi_requires (int fpabi, const char *what)
{
as_warn (_(".gnu_attribute %d,%d requires `%s'"),
Tag_GNU_MIPS_ABI_FP, fpabi, what);
}
/* Check -mabi and register sizes against the specified FP ABI. */
static void
check_fpabi (int fpabi)
{
bfd_boolean needs_check = FALSE;
switch (fpabi)
{
case Val_GNU_MIPS_ABI_FP_DOUBLE:
if (file_mips_opts.gp == 64 && file_mips_opts.fp == 32)
fpabi_incompatible_with (fpabi, "gp=64 fp=32");
else if (file_mips_opts.gp == 32 && file_mips_opts.fp == 64)
fpabi_incompatible_with (fpabi, "gp=32 fp=64");
else
needs_check = TRUE;
break;
case Val_GNU_MIPS_ABI_FP_XX:
if (mips_abi != O32_ABI)
fpabi_requires (fpabi, "-mabi=32");
else if (file_mips_opts.fp != 0)
fpabi_requires (fpabi, "fp=xx");
else
needs_check = TRUE;
break;
case Val_GNU_MIPS_ABI_FP_64A:
case Val_GNU_MIPS_ABI_FP_64:
if (mips_abi != O32_ABI)
fpabi_requires (fpabi, "-mabi=32");
else if (file_mips_opts.fp != 64)
fpabi_requires (fpabi, "fp=64");
else if (fpabi == Val_GNU_MIPS_ABI_FP_64 && !file_mips_opts.oddspreg)
fpabi_incompatible_with (fpabi, "nooddspreg");
else if (fpabi == Val_GNU_MIPS_ABI_FP_64A && file_mips_opts.oddspreg)
fpabi_requires (fpabi, "nooddspreg");
else
needs_check = TRUE;
break;
case Val_GNU_MIPS_ABI_FP_SINGLE:
if (file_mips_opts.soft_float)
fpabi_incompatible_with (fpabi, "softfloat");
else if (!file_mips_opts.single_float)
fpabi_requires (fpabi, "singlefloat");
break;
case Val_GNU_MIPS_ABI_FP_SOFT:
if (!file_mips_opts.soft_float)
fpabi_requires (fpabi, "softfloat");
break;
case Val_GNU_MIPS_ABI_FP_OLD_64:
as_warn (_(".gnu_attribute %d,%d is no longer supported"),
Tag_GNU_MIPS_ABI_FP, fpabi);
break;
default:
as_warn (_(".gnu_attribute %d,%d is not a recognized"
" floating-point ABI"), Tag_GNU_MIPS_ABI_FP, fpabi);
break;
}
if (needs_check && file_mips_opts.soft_float)
fpabi_incompatible_with (fpabi, "softfloat");
else if (needs_check && file_mips_opts.single_float)
fpabi_incompatible_with (fpabi, "singlefloat");
}
/* Perform consistency checks on the current options. */
static void
@ -3653,6 +3754,12 @@ mips_check_options (struct mips_set_options *opts, bfd_boolean abi_checks)
/* Check the size of the float registers agrees with the ABI and ISA. */
switch (opts->fp)
{
case 0:
if (!CPU_HAS_LDC1_SDC1 (opts->arch))
as_bad (_("`fp=xx' used with a cpu lacking ldc1/sdc1 instructions"));
else if (opts->single_float == 1)
as_bad (_("`fp=xx' cannot be used with `singlefloat'"));
break;
case 64:
if (!ISA_HAS_64BIT_FPRS (opts->isa))
as_bad (_("`fp=64' used with a 32-bit fpu"));
@ -3671,6 +3778,9 @@ mips_check_options (struct mips_set_options *opts, bfd_boolean abi_checks)
break;
}
if (ABI_NEEDS_64BIT_REGS (mips_abi) && !opts->oddspreg)
as_bad (_("`nooddspreg` cannot be used with a 64-bit ABI"));
if (opts->micromips == 1 && opts->mips16 == 1)
as_bad (_("`mips16' cannot be used with `micromips'"));
}
@ -3728,6 +3838,16 @@ file_mips_check_options (void)
arch_info = mips_cpu_info_from_arch (file_mips_opts.arch);
/* Disable operations on odd-numbered floating-point registers by default
when using the FPXX ABI. */
if (file_mips_opts.oddspreg < 0)
{
if (file_mips_opts.fp == 0)
file_mips_opts.oddspreg = 0;
else
file_mips_opts.oddspreg = 1;
}
/* End of GCC-shared inference code. */
/* This flag is set when we have a 64-bit capable CPU but use only
@ -4377,39 +4497,42 @@ static bfd_boolean
mips_oddfpreg_ok (const struct mips_opcode *insn, int opnum)
{
const char *s = insn->name;
bfd_boolean oddspreg = (ISA_HAS_ODD_SINGLE_FPR (mips_opts.isa, mips_opts.arch)
|| FPR_SIZE == 64)
&& mips_opts.oddspreg;
if (insn->pinfo == INSN_MACRO)
/* Let a macro pass, we'll catch it later when it is expanded. */
return TRUE;
if (ISA_HAS_ODD_SINGLE_FPR (mips_opts.isa) || mips_opts.arch == CPU_R5900)
{
/* Allow odd registers for single-precision ops. */
switch (insn->pinfo & (FP_S | FP_D))
{
case FP_S:
case 0:
return TRUE;
case FP_D:
return FALSE;
default:
break;
}
/* Single-precision coprocessor loads and moves are OK for 32-bit registers,
otherwise it depends on oddspreg. */
if ((insn->pinfo & FP_S)
&& (insn->pinfo & (INSN_LOAD_MEMORY | INSN_STORE_MEMORY
| INSN_LOAD_COPROC_DELAY | INSN_COPROC_MOVE_DELAY)))
return FPR_SIZE == 32 || oddspreg;
/* Cvt.w.x and cvt.x.w allow an odd register for a 'w' or 's' operand. */
s = strchr (insn->name, '.');
if (s != NULL && opnum == 2)
s = strchr (s + 1, '.');
return (s != NULL && (s[1] == 'w' || s[1] == 's'));
/* Allow odd registers for single-precision ops and double-precision if the
floating-point registers are 64-bit wide. */
switch (insn->pinfo & (FP_S | FP_D))
{
case FP_S:
case 0:
return oddspreg;
case FP_D:
return FPR_SIZE == 64;
default:
break;
}
/* Single-precision coprocessor loads and moves are OK too. */
if ((insn->pinfo & FP_S)
&& (insn->pinfo & (INSN_COPROC_MEMORY_DELAY | INSN_STORE_MEMORY
| INSN_LOAD_COPROC_DELAY | INSN_COPROC_MOVE_DELAY)))
return TRUE;
/* Cvt.w.x and cvt.x.w allow an odd register for a 'w' or 's' operand. */
s = strchr (insn->name, '.');
if (s != NULL && opnum == 2)
s = strchr (s + 1, '.');
if (s != NULL && (s[1] == 'w' || s[1] == 's'))
return oddspreg;
return FALSE;
return FPR_SIZE == 64;
}
/* Information about an instruction argument that we're trying to match. */
@ -4632,9 +4755,16 @@ check_regno (struct mips_arg_info *arg,
if (type == OP_REG_FP
&& (regno & 1) != 0
&& FPR_SIZE != 64
&& !mips_oddfpreg_ok (arg->insn->insn_mo, arg->opnum))
as_warn (_("float register should be even, was %d"), regno);
{
/* This was a warning prior to introducing O32 FPXX and FP64 support
so maintain a warning for FP32 but raise an error for the new
cases. */
if (FPR_SIZE == 32)
as_warn (_("float register should be even, was %d"), regno);
else
as_bad (_("float register should be even, was %d"), regno);
}
if (type == OP_REG_CCC)
{
@ -5488,13 +5618,16 @@ match_float_constant (struct mips_arg_info *arg, expressionS *imm,
/* Handle 64-bit constants for which an immediate value is best. */
if (length == 8
&& !mips_disable_float_construction
/* Constants can only be constructed in GPRs and copied
to FPRs if the GPRs are at least as wide as the FPRs.
Force the constant into memory if we are using 64-bit FPRs
but the GPRs are only 32 bits wide. */
/* ??? No longer true with the addition of MTHC1, but this
is legacy code... */
&& (using_gprs || !(FPR_SIZE == 64 && GPR_SIZE == 32))
/* Constants can only be constructed in GPRs and copied to FPRs if the
GPRs are at least as wide as the FPRs or MTHC1 is available.
Unlike most tests for 32-bit floating-point registers this check
specifically looks for GPR_SIZE == 32 as the FPXX ABI does not
permit 64-bit moves without MXHC1.
Force the constant into memory otherwise. */
&& (using_gprs
|| GPR_SIZE == 64
|| ISA_HAS_MXHC1 (mips_opts.isa)
|| FPR_SIZE == 32)
&& ((data[0] == 0 && data[1] == 0)
|| (data[2] == 0 && data[3] == 0))
&& ((data[4] == 0 && data[5] == 0)
@ -5504,7 +5637,7 @@ match_float_constant (struct mips_arg_info *arg, expressionS *imm,
If using 32-bit registers, set IMM to the high order 32 bits and
OFFSET to the low order 32 bits. Otherwise, set IMM to the entire
64 bit constant. */
if (using_gprs ? GPR_SIZE == 32 : FPR_SIZE != 64)
if (GPR_SIZE == 32 || (!using_gprs && FPR_SIZE != 64))
{
imm->X_op = O_constant;
offset->X_op = O_constant;
@ -11686,14 +11819,18 @@ macro (struct mips_cl_insn *ip, char *str)
{
used_at = 1;
load_register (AT, &imm_expr, FPR_SIZE == 64);
if (FPR_SIZE == 64)
{
gas_assert (GPR_SIZE == 64);
macro_build (NULL, "dmtc1", "t,S", AT, op[0]);
}
if (FPR_SIZE == 64 && GPR_SIZE == 64)
macro_build (NULL, "dmtc1", "t,S", AT, op[0]);
else
{
macro_build (NULL, "mtc1", "t,G", AT, op[0] + 1);
if (ISA_HAS_MXHC1 (mips_opts.isa))
macro_build (NULL, "mthc1", "t,G", AT, op[0]);
else if (FPR_SIZE != 32)
as_bad (_("Unable to generate `%s' compliant code "
"without mthc1"),
(FPR_SIZE == 64) ? "fp64" : "fpxx");
else
macro_build (NULL, "mtc1", "t,G", AT, op[0] + 1);
if (offset_expr.X_op == O_absent)
macro_build (NULL, "mtc1", "t,G", 0, op[0]);
else
@ -13939,10 +14076,22 @@ md_parse_option (int c, char *arg)
file_mips_opts.fp = 32;
break;
case OPTION_FPXX:
file_mips_opts.fp = 0;
break;
case OPTION_FP64:
file_mips_opts.fp = 64;
break;
case OPTION_ODD_SPREG:
file_mips_opts.oddspreg = 1;
break;
case OPTION_NO_ODD_SPREG:
file_mips_opts.oddspreg = 0;
break;
case OPTION_SINGLE_FLOAT:
file_mips_opts.single_float = 1;
break;
@ -15031,6 +15180,8 @@ parse_code_option (char * name)
mips_opts.gp = 64;
else if (strcmp (name, "fp=32") == 0)
mips_opts.fp = 32;
else if (strcmp (name, "fp=xx") == 0)
mips_opts.fp = 0;
else if (strcmp (name, "fp=64") == 0)
mips_opts.fp = 64;
else if (strcmp (name, "softfloat") == 0)
@ -15041,6 +15192,10 @@ parse_code_option (char * name)
mips_opts.single_float = 1;
else if (strcmp (name, "doublefloat") == 0)
mips_opts.single_float = 0;
else if (strcmp (name, "nooddspreg") == 0)
mips_opts.oddspreg = 0;
else if (strcmp (name, "oddspreg") == 0)
mips_opts.oddspreg = 1;
else if (strcmp (name, "mips16") == 0
|| strcmp (name, "MIPS-16") == 0)
mips_opts.mips16 = 1;
@ -15202,13 +15357,17 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
case 0:
break;
case ISA_MIPS1:
/* MIPS I cannot support FPXX. */
mips_opts.fp = 32;
/* fall-through. */
case ISA_MIPS2:
case ISA_MIPS32:
case ISA_MIPS32R2:
case ISA_MIPS32R3:
case ISA_MIPS32R5:
mips_opts.gp = 32;
mips_opts.fp = 32;
if (mips_opts.fp != 0)
mips_opts.fp = 32;
break;
case ISA_MIPS3:
case ISA_MIPS4:
@ -15218,10 +15377,13 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
case ISA_MIPS64R3:
case ISA_MIPS64R5:
mips_opts.gp = 64;
if (mips_opts.arch == CPU_R5900)
mips_opts.fp = 32;
else
mips_opts.fp = 64;
if (mips_opts.fp != 0)
{
if (mips_opts.arch == CPU_R5900)
mips_opts.fp = 32;
else
mips_opts.fp = 64;
}
break;
default:
as_bad (_("unknown ISA level %s"), name + 4);
@ -17371,11 +17533,123 @@ mips_add_dot_label (symbolS *sym)
mips_compressed_mark_label (sym);
}
/* Converting ASE flags from internal to .MIPS.abiflags values. */
static unsigned int
mips_convert_ase_flags (int ase)
{
unsigned int ext_ases = 0;
if (ase & ASE_DSP)
ext_ases |= AFL_ASE_DSP;
if (ase & ASE_DSPR2)
ext_ases |= AFL_ASE_DSPR2;
if (ase & ASE_EVA)
ext_ases |= AFL_ASE_EVA;
if (ase & ASE_MCU)
ext_ases |= AFL_ASE_MCU;
if (ase & ASE_MDMX)
ext_ases |= AFL_ASE_MDMX;
if (ase & ASE_MIPS3D)
ext_ases |= AFL_ASE_MIPS3D;
if (ase & ASE_MT)
ext_ases |= AFL_ASE_MT;
if (ase & ASE_SMARTMIPS)
ext_ases |= AFL_ASE_SMARTMIPS;
if (ase & ASE_VIRT)
ext_ases |= AFL_ASE_VIRT;
if (ase & ASE_MSA)
ext_ases |= AFL_ASE_MSA;
if (ase & ASE_XPA)
ext_ases |= AFL_ASE_XPA;
return ext_ases;
}
/* Some special processing for a MIPS ELF file. */
void
mips_elf_final_processing (void)
{
int fpabi;
Elf_Internal_ABIFlags_v0 flags;
flags.version = 0;
flags.isa_rev = 0;
switch (file_mips_opts.isa)
{
case INSN_ISA1:
flags.isa_level = 1;
break;
case INSN_ISA2:
flags.isa_level = 2;
break;
case INSN_ISA3:
flags.isa_level = 3;
break;
case INSN_ISA4:
flags.isa_level = 4;
break;
case INSN_ISA5:
flags.isa_level = 5;
break;
case INSN_ISA32:
flags.isa_level = 32;
flags.isa_rev = 1;
break;
case INSN_ISA32R2:
flags.isa_level = 32;
flags.isa_rev = 2;
break;
case INSN_ISA32R3:
flags.isa_level = 32;
flags.isa_rev = 3;
break;
case INSN_ISA32R5:
flags.isa_level = 32;
flags.isa_rev = 5;
break;
case INSN_ISA64:
flags.isa_level = 64;
flags.isa_rev = 1;
break;
case INSN_ISA64R2:
flags.isa_level = 64;
flags.isa_rev = 2;
break;
case INSN_ISA64R3:
flags.isa_level = 64;
flags.isa_rev = 3;
break;
case INSN_ISA64R5:
flags.isa_level = 64;
flags.isa_rev = 5;
break;
}
flags.gpr_size = file_mips_opts.gp == 32 ? AFL_REG_32 : AFL_REG_64;
flags.cpr1_size = file_mips_opts.soft_float ? AFL_REG_NONE
: (file_mips_opts.ase & ASE_MSA) ? AFL_REG_128
: (file_mips_opts.fp == 64) ? AFL_REG_64
: AFL_REG_32;
flags.cpr2_size = AFL_REG_NONE;
flags.fp_abi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
Tag_GNU_MIPS_ABI_FP);
flags.isa_ext = bfd_mips_isa_ext (stdoutput);
flags.ases = mips_convert_ase_flags (file_mips_opts.ase);
if (file_ase_mips16)
flags.ases |= AFL_ASE_MIPS16;
if (file_ase_micromips)
flags.ases |= AFL_ASE_MICROMIPS;
flags.flags1 = 0;
if ((ISA_HAS_ODD_SINGLE_FPR (file_mips_opts.isa, file_mips_opts.arch)
|| file_mips_opts.fp == 64)
&& file_mips_opts.oddspreg)
flags.flags1 |= AFL_FLAGS1_ODDSPREG;
flags.flags2 = 0;
bfd_mips_elf_swap_abiflags_v0_out (stdoutput, &flags,
((Elf_External_ABIFlags_v0 *)
mips_flags_frag));
/* Write out the register information. */
if (mips_abi != N64_ABI)
{
@ -17454,7 +17728,9 @@ mips_elf_final_processing (void)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_NAN2008;
/* 32 bit code with 64 bit FP registers. */
if (file_mips_opts.fp == 64 && ABI_NEEDS_32BIT_REGS (mips_abi))
fpabi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
Tag_GNU_MIPS_ABI_FP);
if (fpabi == Val_GNU_MIPS_ABI_FP_OLD_64)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_FP64;
}
@ -18402,10 +18678,56 @@ mips_convert_symbolic_attribute (const char *name)
void
md_mips_end (void)
{
int fpabi = Val_GNU_MIPS_ABI_FP_ANY;
mips_emit_delays ();
if (cur_proc_ptr)
as_warn (_("missing .end at end of assembly"));
/* Just in case no code was emitted, do the consistency check. */
file_mips_check_options ();
/* Set a floating-point ABI if the user did not. */
if (obj_elf_seen_attribute (OBJ_ATTR_GNU, Tag_GNU_MIPS_ABI_FP))
{
/* Perform consistency checks on the floating-point ABI. */
fpabi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
Tag_GNU_MIPS_ABI_FP);
if (fpabi != Val_GNU_MIPS_ABI_FP_ANY)
check_fpabi (fpabi);
}
else
{
/* Soft-float gets precedence over single-float, the two options should
not be used together so this should not matter. */
if (file_mips_opts.soft_float == 1)
fpabi = Val_GNU_MIPS_ABI_FP_SOFT;
/* Single-float gets precedence over all double_float cases. */
else if (file_mips_opts.single_float == 1)
fpabi = Val_GNU_MIPS_ABI_FP_SINGLE;
else
{
switch (file_mips_opts.fp)
{
case 32:
if (file_mips_opts.gp == 32)
fpabi = Val_GNU_MIPS_ABI_FP_DOUBLE;
break;
case 0:
fpabi = Val_GNU_MIPS_ABI_FP_XX;
break;
case 64:
if (file_mips_opts.gp == 32 && !file_mips_opts.oddspreg)
fpabi = Val_GNU_MIPS_ABI_FP_64A;
else if (file_mips_opts.gp == 32)
fpabi = Val_GNU_MIPS_ABI_FP_64;
else
fpabi = Val_GNU_MIPS_ABI_FP_DOUBLE;
break;
}
}
bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
Tag_GNU_MIPS_ABI_FP, fpabi);
}
}

View File

@ -399,6 +399,8 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-g}[@var{debug level}]] [@b{-G} @var{num}] [@b{-KPIC}] [@b{-call_shared}]
[@b{-non_shared}] [@b{-xgot} [@b{-mvxworks-pic}]
[@b{-mabi}=@var{ABI}] [@b{-32}] [@b{-n32}] [@b{-64}] [@b{-mfp32}] [@b{-mgp32}]
[@b{-mfp64}] [@b{-mgp64}] [@b{-mfpxx}]
[@b{-modd-spreg}] [@b{-mno-odd-spreg}]
[@b{-march}=@var{CPU}] [@b{-mtune}=@var{CPU}] [@b{-mips1}] [@b{-mips2}]
[@b{-mips3}] [@b{-mips4}] [@b{-mips5}] [@b{-mips32}] [@b{-mips32r2}]
[@b{-mips32r3}] [@b{-mips32r5}] [@b{-mips64}] [@b{-mips64r2}]
@ -1321,6 +1323,25 @@ flags force a certain group of registers to be treated as 32 bits wide at
all times. @samp{-mgp32} controls the size of general-purpose registers
and @samp{-mfp32} controls the size of floating-point registers.
@item -mgp64
@itemx -mfp64
The register sizes are normally inferred from the ISA and ABI, but these
flags force a certain group of registers to be treated as 64 bits wide at
all times. @samp{-mgp64} controls the size of general-purpose registers
and @samp{-mfp64} controls the size of floating-point registers.
@item -mfpxx
The register sizes are normally inferred from the ISA and ABI, but using
this flag in combination with @samp{-mabi=32} enables an ABI variant
which will operate correctly with floating-point registers which are
32 or 64 bits wide.
@item -modd-spreg
@itemx -mno-odd-spreg
Enable use of floating-point operations on odd-numbered single-precision
registers when supported by the ISA. @samp{-mfpxx} implies
@samp{-mno-odd-spreg}, otherwise the default is @samp{-modd-spreg}.
@item -mips16
@itemx -no-mips16
Generate code for the MIPS 16 processor. This is equivalent to putting

View File

@ -28,6 +28,7 @@ Assembly Language Programming'' in the same work.
* MIPS assembly options:: Directives to control code generation
* MIPS autoextend:: Directives for extending MIPS 16 bit instructions
* MIPS insn:: Directive to mark data as an instruction
* MIPS FP ABIs:: Marking which FP ABI is in use
* MIPS NaN Encodings:: Directives to record which NaN encoding is being used
* MIPS Option Stack:: Directives to save and restore options
* MIPS ASE Instruction Generation Overrides:: Directives to control
@ -125,6 +126,22 @@ The @code{.set gp=64} and @code{.set fp=64} directives allow the size
of registers to be changed for parts of an object. The default value is
restored by @code{.set gp=default} and @code{.set fp=default}.
@item -mfpxx
Make no assumptions about whether 32-bit or 64-bit floating-point
registers are available. This is provided to support having modules
compatible with either @samp{-mfp32} or @samp{-mfp64}. This option can
only be used with MIPS II and above.
The @code{.set fp=xx} directive allows a part of an object to be marked
as not making assumptions about 32-bit or 64-bit FP registers. The
default value is restored by @code{.set fp=default}.
@item -modd-spreg
@itemx -mno-odd-spreg
Enable use of floating-point operations on odd-numbered single-precision
registers when supported by the ISA. @samp{-mfpxx} implies
@samp{-mno-odd-spreg}, otherwise the default is @samp{-modd-spreg}
@item -mips16
@itemx -no-mips16
Generate code for the MIPS 16 processor. This is equivalent to putting
@ -769,6 +786,115 @@ baz:
@end example
@node MIPS FP ABIs
@section Directives to control the FP ABI
@menu
* MIPS FP ABI History:: History of FP ABIs
* MIPS FP ABI Variants:: Supported FP ABIs
* MIPS FP ABI Selection:: Automatic selection of FP ABI
* MIPS FP ABI Compatibility:: Linking different FP ABI variants
@end menu
@node MIPS FP ABI History
@subsection History of FP ABIs
@cindex @code{.gnu_attribute 4, @var{n}} directive, MIPS
@cindex @code{.gnu_attribute Tag_GNU_MIPS_ABI_FP, @var{n}} directive, MIPS
The MIPS ABIs support a variety of different floating-point extensions
where calling-convention and register sizes vary for floating-point data.
The extensions exist to support a wide variety of optional architecture
features. The resulting ABI variants are generally incompatible with each
other and must be tracked carefully.
Traditionally the use of an explicit @code{.gnu_attribute 4, @var{n}}
directive is used to indicate which ABI is in use by a specific module.
It was then left to the user to ensure that command line options and the
selected ABI were compatible with some potential for inconsistencies.
@node MIPS FP ABI Variants
@subsection Supported FP ABIs
The supported floating-point ABI variants are:
@table @code
@item 0 - No floating-point
This variant is used to indicate that floating-point is not used within
the module at all and therefore has no impact on the ABI. This is the
default.
@item 1 - Double-precision
This variant indicates that double-precision support is used. For 64-bit
ABIs this means that 64-bit wide floating-point registers are required.
For 32-bit ABIs this means that 32-bit wide floating-point registers are
required and double-precision operations use pairs of registers.
@item 2 - Single-precision
This variant indicates that single-precision support is used. Double
precision operations will be supported via soft-float routines.
@item 3 - Soft-float
This variant indicates that although floating-point support is used all
operations are emulated in software. This means the ABI is modified to
pass all floating-point data in general-purpose registers.
@item 4 - Deprecated
This variant existed as an initial attempt at supporting 64-bit wide
floating-point registers for O32 ABI on a MIPS32r2 cpu. This has been
superceded by @value{5}, @value{6} and @value{7}.
@item 5 - Double-precision 32-bit CPU, 32-bit or 64-bit FPU
This variant is used by 32-bit ABIs to indicate that the floating-point
code in the module has been designed to operate correctly with either
32-bit wide or 64-bit wide floating-point registers. Double-precision
support is used. Only O32 currently supports this variant and requires
a minimum architecture of MIPS II.
@item 6 - Double-precision 32-bit FPU, 64-bit FPU
This variant is used by 32-bit ABIs to indicate that the floating-point
code in the module requires 64-bit wide floating-point registers.
Double-precision support is used. Only O32 currently supports this
variant and requires a minimum architecture of MIPS32r2.
@item 7 - Double-precision compat 32-bit FPU, 64-bit FPU
This variant is used by 32-bit ABIs to indicate that the floating-point
code in the module requires 64-bit wide floating-point registers.
Double-precision support is used. This differs from the previous ABI
as it restricts use of odd-numbered single-precision registers. Only
O32 currently supports this variant and requires a minimum architecture
of MIPS32r2.
@end table
@node MIPS FP ABI Selection
@subsection Automatic selection of FP ABI
@cindex @code{.module fp=@var{nn}} directive, MIPS
In order to simplify and add safety to the process of selecting the
correct floating-point ABI, the assembler will automatically infer the
correct @code{.gnu_attribute 4, @var{n}} directive based on command line
options and @code{.module} overrides. Where an explicit
@code{.gnu_attribute 4, @var{n}} directive has been seen then a warning
will be raised if it does not match an inferred setting.
The floating-point ABI is inferred as follows. If @samp{-msoft-float}
has been used the module will be marked as soft-float. If
@samp{-msingle-float} has been used then the module will be marked as
single-precision. The remaining ABIs are then selected based
on the FP register width. Double-precision is selected if the width
of GP and FP registers match and the special double-precision variants
for 32-bit ABIs are then selected depending on @samp{-mfpxx},
@samp{-mfp64} and @samp{-mno-odd-spreg}.
@node MIPS FP ABI Compatibility
@subsection Linking different FP ABI variants
Modules using the default FP ABI (no floating-point) can be linked with
any other (singular) FP ABI variant.
Special compatibility support exists for O32 with the four
double-precision FP ABI variants. The @samp{-mfpxx} FP ABI is specifically
designed to be compatible with the standard double-precision ABI and the
@samp{-mfp64} FP ABIs. This makes it desirable for O32 modules to be
built as @samp{-mfpxx} to ensure the maximum compatibility with other
modules produced for more specific needs. The only FP ABIs which cannot
be linked together are the standard double-precision ABI and the full
@samp{-mfp64} ABI with @samp{-modd-spreg}.
@node MIPS NaN Encodings
@section Directives to record which NaN encoding is being used

View File

@ -1,3 +1,127 @@
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* gas/mips/attr-gnu-4-0.d: New.
* gas/mips/attr-gnu-4-0.s: Likewise.
* gas/mips/attr-gnu-4-1-mfp32.l: Likewise.
* gas/mips/attr-gnu-4-1-mfp32.s: Likewise.
* gas/mips/attr-gnu-4-1-mfp64.l: Likewise.
* gas/mips/attr-gnu-4-1-mfp64.s: Likewise.
* gas/mips/attr-gnu-4-1-mfpxx.s: Likewise.
* gas/mips/attr-gnu-4-1-msingle-float.l: Likewise.
* gas/mips/attr-gnu-4-1-msingle-float.s: Likewise.
* gas/mips/attr-gnu-4-1-msoft-float.l: Likewise.
* gas/mips/attr-gnu-4-1-msoft-float.s: Likewise.
* gas/mips/attr-gnu-4-1.d: Likewise.
* gas/mips/attr-gnu-4-1.s: Likewise.
* gas/mips/attr-gnu-4-2-mdouble-float.l: Likewise.
* gas/mips/attr-gnu-4-2-mdouble-float.s: Likewise.
* gas/mips/attr-gnu-4-2-msoft-float.l: Likewise.
* gas/mips/attr-gnu-4-2-msoft-float.s: Likewise.
* gas/mips/attr-gnu-4-2.d: Likewise.
* gas/mips/attr-gnu-4-2.s: Likewise.
* gas/mips/attr-gnu-4-3-mhard-float.l: Likewise.
* gas/mips/attr-gnu-4-3-mhard-float.s: Likewise.
* gas/mips/attr-gnu-4-3.d: Likewise.
* gas/mips/attr-gnu-4-3.s: Likewise.
* gas/mips/attr-gnu-4-4.l: Likewise.
* gas/mips/attr-gnu-4-4.s: Likewise.
* gas/mips/attr-gnu-4-5-64.l: Likewise.
* gas/mips/attr-gnu-4-5-64.s: Likewise.
* gas/mips/attr-gnu-4-5.d: Likewise.
* gas/mips/attr-gnu-4-5.l: Likewise.
* gas/mips/attr-gnu-4-5.s: Likewise.
* gas/mips/attr-gnu-4-6-64.l: Likewise.
* gas/mips/attr-gnu-4-6-64.s: Likewise.
* gas/mips/attr-gnu-4-6.d: Likewise.
* gas/mips/attr-gnu-4-6.l: Likewise.
* gas/mips/attr-gnu-4-6.s: Likewise.
* gas/mips/attr-gnu-4-6-msingle-float.l: Likewise.
* gas/mips/attr-gnu-4-6-msingle-float.s: Likewise.
* gas/mips/attr-gnu-4-6-msoft-float.l: Likewise.
* gas/mips/attr-gnu-4-6-msoft-float.s: Likewise.
* gas/mips/attr-gnu-4-6-noodd.l: Likewise.
* gas/mips/attr-gnu-4-6-noodd.s: Likewise.
* gas/mips/attr-gnu-4-7-64.l: Likewise.
* gas/mips/attr-gnu-4-7-64.s: Likewise.
* gas/mips/attr-gnu-4-7-msingle-float.l: Likewise.
* gas/mips/attr-gnu-4-7-msingle-float.s: Likewise.
* gas/mips/attr-gnu-4-7-msoft-float.l: Likewise.
* gas/mips/attr-gnu-4-7-msoft-float.s: Likewise.
* gas/mips/attr-gnu-4-7-odd.l: Likewise.
* gas/mips/attr-gnu-4-7-odd.s: Likewise.
* gas/mips/attr-gnu-4-7.d: Likewise.
* gas/mips/attr-gnu-4-7.l: Likewise.
* gas/mips/attr-gnu-4-7.s: Likewise.
* gas/mips/attr-none-double.d: Likewise.
* gas/mips/attr-none-o32-fp64.d: Likewise.
* gas/mips/attr-none-o32-fp64-nooddspreg.d
* gas/mips/attr-none-o32-fpxx.d: Likewise.
* gas/mips/attr-none-single-float.d: Likewise.
* gas/mips/attr-none-soft-float.d: Likewise.
* gas/mips/elf_arch_mips32r3.d: Likewise.
* gas/mips/elf_arch_mips32r5.d: Likewise.
* gas/mips/elf_arch_mips64r3.d: Likewise.
* gas/mips/elf_arch_mips64r5.d: Likewise.
* gas/mips/li-d.d: Likewise.
* gas/mips/li-d.s: Likewise.
* gas/mips/module-check-warn.l: Likewise.
* gas/mips/module-check-warn.s: Likewise.
* gas/mips/module-check.d: Likewise.
* gas/mips/module-check.s: Likewise.
* gas/mips/module-mfp32.d: Likewise.
* gas/mips/module-mfp32.s: Likewise.
* gas/mips/module-mfp64.d: Likewise.
* gas/mips/module-mfp64.s: Likewise.
* gas/mips/module-mfp64-noodd.d: Likewise.
* gas/mips/module-mfp64-noodd.s: Likewise.
* gas/mips/module-mfpxx.d: Likewise.
* gas/mips/module-mfpxx.s: Likewise.
* gas/mips/module-msingle-float.d: Likewise.
* gas/mips/module-msingle-float.s: Likewise.
* gas/mips/module-msoft-float.d: Likewise.
* gas/mips/module-msoft-float.s: Likewise.
* gas/mips/module-set-mfpxx.d: Likewise.
* gas/mips/module-set-mfpxx.s: Likewise.
* gas/mips/fpxx-oddfpreg.d: Likewise.
* gas/mips/fpxx-oddfpreg.l: Likewise.
* gas/mips/fpxx-oddfpreg.s: Likewise.
* gas/mips/no-odd-spreg.d: Likewise.
* gas/mips/odd-spreg.d: Likewise.
* gas/elf/section2.e-mips: Adjust expected output.
* gas/mips/attr-gnu-abi-fp-1.d: Likewise.
* gas/mips/attr-gnu-abi-msa-1.d: Likewise.
* gas/mips/call-nonpic-1.d: Likewise.
* gas/mips/elf_arch_mips1.d: Likewise.
* gas/mips/elf_arch_mips2.d: Likewise.
* gas/mips/elf_arch_mips3.d: Likewise.
* gas/mips/elf_arch_mips32.d: Likewise.
* gas/mips/elf_arch_mips32r2.d: Likewise.
* gas/mips/elf_arch_mips4.d: Likewise.
* gas/mips/elf_arch_mips5.d: Likewise.
* gas/mips/elf_arch_mips64.d: Likewise.
* gas/mips/elf_arch_mips64r2.d: Likewise.
* gas/mips/elf_ase_micromips-2.d: Likewise.
* gas/mips/elf_ase_micromips.d: Likewise.
* gas/mips/elf_ase_mips16-2.d: Likewise.
* gas/mips/elf_ase_mips16.d: Likewise.
* gas/mips/module-defer-warn1.d: Likewise.
* gas/mips/module-override.d: Likewise.
* gas/mips/n32-consec.d: Likewise.
* gas/mips/nan-2008-1.d: Likewise.
* gas/mips/nan-2008-2.d: Likewise.
* gas/mips/nan-2008-3.d: Likewise.
* gas/mips/nan-2008-4.d: Likewise.
* gas/mips/nan-legacy-1.d: Likewise.
* gas/mips/nan-legacy-2.d: Likewise.
* gas/mips/nan-legacy-3.d: Likewise.
* gas/mips/nan-legacy-4.d: Likewise.
* gas/mips/nan-legacy-5.d: Likewise.
* gas/mips/tmips16-e.d: Likewise.
* gas/mips/tmips16-f.d: Likewise.
* gas/mips/tmipsel16-e.d: Likewise.
* gas/mips/tmipsel16-f.d: Likewise.
* gas/testsuite/gas/mips/mips.exp: Add new tests.
2014-07-22 Sergey Guriev <sergey.s.guriev@intel.com>
Alexander Ivchenko <alexander.ivchenko@intel.com>
Maxim Kuznetsov <maxim.kuznetsov@intel.com>

View File

@ -1,10 +1,12 @@
Symbol table '.symtab' contains 7 entries:
Symbol table '.symtab' contains 9 entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+0: 0+0 +0 +NOTYPE +LOCAL +DEFAULT +UND
+1: 0+0 +0 +SECTION +LOCAL +DEFAULT +1 (|\.text)
+2: 0+0 +0 +SECTION +LOCAL +DEFAULT +2 (|\.data)
+3: 0+0 +0 +SECTION +LOCAL +DEFAULT +3 (|\.bss)
+4: 0+0 +0 +SECTION +LOCAL +DEFAULT +6 (|A)
+4: 0+0 +0 +SECTION +LOCAL +DEFAULT +7 (|A)
+5: 0+0 +0 +SECTION +LOCAL +DEFAULT +4 (|\.reginfo)
+6: 0+0 +0 +SECTION +LOCAL +DEFAULT +5 (|\.pdr)
+6: 0+0 +0 +SECTION +LOCAL +DEFAULT +5 (|\.MIPS\.abiflags)
+7: 0+0 +0 +SECTION +LOCAL +DEFAULT +6 (|\.pdr)
+8: 0+0 +0 +SECTION +LOCAL +DEFAULT +8 (|\.gnu\.attributes)

View File

@ -0,0 +1,17 @@
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,0
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard or soft float
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1 @@
.gnu_attribute 4,0

View File

@ -0,0 +1,3 @@
.*: Assembler messages:
.*: Warning: `fp=32' used with a 64-bit ABI
.*: Warning: .gnu_attribute 4,1 is incompatible with `gp=64 fp=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,1

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,1 is incompatible with `gp=32 fp=64'

View File

@ -0,0 +1 @@
.gnu_attribute 4,1

View File

@ -0,0 +1 @@
.gnu_attribute 4,1

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,1 is incompatible with `singlefloat'

View File

@ -0,0 +1 @@
.gnu_attribute 4,1

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,1 is incompatible with `softfloat'

View File

@ -0,0 +1 @@
.gnu_attribute 4,1

View File

@ -0,0 +1,22 @@
#source: attr-gnu-4-1.s
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,1 (double precision)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(double precision\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1 @@
.gnu_attribute 4,1

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,2 requires `singlefloat'

View File

@ -0,0 +1 @@
.gnu_attribute 4,2

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,2 is incompatible with `softfloat'

View File

@ -0,0 +1 @@
.gnu_attribute 4,2

View File

@ -0,0 +1,23 @@
#source: attr-gnu-4-2.s
#as: -msingle-float
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,2 (single precision)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(single precision\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard float \(single precision\)
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1 @@
.gnu_attribute 4,2

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,3 requires `softfloat'

View File

@ -0,0 +1 @@
.gnu_attribute 4,3

View File

@ -0,0 +1,23 @@
#as: -msoft-float
#source: attr-gnu-4-3.s
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,3 (-msoft-float)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Soft float
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: .*
CPR2 size: 0
FP ABI: Soft float
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1 @@
.gnu_attribute 4,3

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,4 is no longer supported

View File

@ -0,0 +1 @@
.gnu_attribute 4,4

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,5 requires `-mabi=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,5

View File

@ -0,0 +1,23 @@
#as: -32 -mfpxx
#source: attr-gnu-4-5.s
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,5 (-mfpxx)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(32-bit CPU, Any FPU\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(32-bit CPU, Any FPU\)
ISA Extension: .*
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,5 requires `fp=xx'

View File

@ -0,0 +1 @@
.gnu_attribute 4,5

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 requires `-mabi=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 is incompatible with `nooddspreg'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,23 @@
#as: -32
#source: attr-gnu-4-6.s
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,6 (-mfp64)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(32-bit CPU, 64-bit FPU\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard float \(32-bit CPU, 64-bit FPU\)
ISA Extension: .*
ASEs:
None
FLAGS 1: 00000001
FLAGS 2: 00000000

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 requires `fp=64'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,7 requires `-mabi=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,7

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'

View File

@ -0,0 +1 @@
.gnu_attribute 4,6

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,7 requires `nooddspreg'

View File

@ -0,0 +1 @@
.gnu_attribute 4,7

View File

@ -0,0 +1,23 @@
#as: -32
#source: attr-gnu-4-7.s
#PROG: readelf
#readelf: -A
#name: MIPS gnu_attribute 4,7 (-mfp64 -mno-odd-spreg)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float compat \(32-bit CPU, 64-bit FPU\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard float compat \(32-bit CPU, 64-bit FPU\)
ISA Extension: .*
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Warning: .gnu_attribute 4,7 requires `fp=64'

View File

@ -0,0 +1 @@
.gnu_attribute 4,7

View File

@ -6,3 +6,17 @@
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(double precision\)
MIPS ABI Flags Version: 0
ISA: MIPS1
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -4,4 +4,7 @@
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(double precision\)
Tag_GNU_MIPS_ABI_MSA: 128-bit MSA
#...

View File

@ -0,0 +1,22 @@
#PROG: readelf
#source: empty.s
#readelf: -A
#name: MIPS infer fpabi (double-precision)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(double precision\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,23 @@
#as: -mfp64 -mno-odd-spreg -32
#source: empty.s
#PROG: readelf
#readelf: -A
#name: MIPS infer fpabi (O32 fp64 nooddspreg)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float compat \(32-bit CPU, 64-bit FPU\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 64
CPR2 size: 0
FP ABI: Hard float compat \(32-bit CPU, 64-bit FPU\)
ISA Extension: .*
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -0,0 +1,23 @@
#as: -mfp64 -32
#source: empty.s
#PROG: readelf
#readelf: -A
#name: MIPS infer fpabi (O32 fp64)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(32-bit CPU, 64-bit FPU\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 64
CPR2 size: 0
FP ABI: Hard float \(32-bit CPU, 64-bit FPU\)
ISA Extension: .*
ASEs:
None
FLAGS 1: 00000001
FLAGS 2: 00000000

View File

@ -0,0 +1,23 @@
#as: -mfpxx -32
#source: empty.s
#PROG: readelf
#readelf: -A
#name: MIPS infer fpabi (O32 fpxx)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(32-bit CPU, Any FPU\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(32-bit CPU, Any FPU\)
ISA Extension: .*
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,23 @@
#as: -msingle-float
#PROG: readelf
#source: empty.s
#readelf: -A
#name: MIPS infer fpabi (single-precision)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Hard float \(single precision\)
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: .*
CPR2 size: 0
FP ABI: Hard float \(single precision\)
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,23 @@
#as: -msoft-float
#PROG: readelf
#source: empty.s
#readelf: -A
#name: MIPS infer fpabi (soft-precision)
Attribute Section: gnu
File Attributes
Tag_GNU_MIPS_ABI_FP: Soft float
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: .*
CPR1 size: 0
CPR2 size: 0
FP ABI: Soft float
ISA Extension: .*
ASEs:
#...
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -4,6 +4,19 @@
.*
private flags = 10001004: .*
MIPS ABI Flags Version: 0
ISA: MIPS2
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000
Disassembly of section \.text:

View File

@ -8,3 +8,16 @@
# flags are _not_ 8 chars long.
private flags = (.......|......|.....|....|...|..|.): .*\[mips1\].*
MIPS ABI Flags Version: 0
ISA: MIPS1
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 1.......: .*\[mips2\].*
MIPS ABI Flags Version: 0
ISA: MIPS2
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 2.......: .*\[mips3\].*
MIPS ABI Flags Version: 0
ISA: MIPS3
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 5.......: .*\[mips32\].*
MIPS ABI Flags Version: 0
ISA: MIPS32
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 7.......: .*\[mips32r2\].*
MIPS ABI Flags Version: 0
ISA: MIPS32r2
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,21 @@
# name: ELF MIPS32r3 markings
# source: empty.s
# objdump: -p
# as: -32 -march=mips32r3
.*:.*file format.*elf.*mips.*
private flags = 7.......: .*\[mips32r2\].*
MIPS ABI Flags Version: 0
ISA: MIPS32r3
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,21 @@
# name: ELF MIPS32r5 markings
# source: empty.s
# objdump: -p
# as: -32 -march=mips32r5
.*:.*file format.*elf.*mips.*
private flags = 7.......: .*\[mips32r2\].*
MIPS ABI Flags Version: 0
ISA: MIPS32r5
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 3.......: .*\[mips4\].*
MIPS ABI Flags Version: 0
ISA: MIPS4
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 4.......: .*\[mips5\].*
MIPS ABI Flags Version: 0
ISA: MIPS5
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*elf.*mips.*
private flags = 6.......: .*\[mips64\].*
MIPS ABI Flags Version: 0
ISA: MIPS64
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -1,8 +1,21 @@
# name: ELF MIPS64r2 markings
# source: empty.s
# objdump: -p
# as: -march=mips64r2
# as: -32 -march=mips64r2
.*:.*file format.*elf.*mips.*
private flags = 8.......: .*\[mips64r2\].*
MIPS ABI Flags Version: 0
ISA: MIPS64r2
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,21 @@
# name: ELF MIPS64r3 markings
# source: empty.s
# objdump: -p
# as: -32 -march=mips64r3
.*:.*file format.*elf.*mips.*
private flags = 8.......: .*\[mips64r2\].*
MIPS ABI Flags Version: 0
ISA: MIPS64r3
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -0,0 +1,21 @@
# name: ELF MIPS64r5 markings
# source: empty.s
# objdump: -p
# as: -32 -march=mips64r5
.*:.*file format.*elf.*mips.*
private flags = 8.......: .*\[mips64r2\].*
MIPS ABI Flags Version: 0
ISA: MIPS64r5
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 0000000.
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*mips.*
private flags = [0-9a-f]*[2367abef]......: .*[[,]micromips[],].*
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
MICROMIPS ASE
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*mips.*
!private flags = .*micromips.*
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*mips.*
private flags = [0-9a-f]*[4-7c-f]......: .*[[,]mips16[],].*
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
MIPS16 ASE
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -6,3 +6,16 @@
.*:.*file format.*mips.*
!private flags = .*mips16.*
MIPS ABI Flags Version: 0
ISA: MIPS.*
GPR size: 32
CPR1 size: 32
CPR2 size: 0
FP ABI: Hard float \(double precision\)
ISA Extension: None
ASEs:
None
FLAGS 1: 00000000
FLAGS 2: 00000000

View File

@ -0,0 +1,12 @@
#as: -32 -mfpxx -modd-spreg
#objdump: -d
#name: FPXX with odd-singles test
.*: file format .*
Disassembly of section .text:
[ 0-9a-f]+ <.text>:
[ 0-9a-f]+: 44840800 mtc1 a0,\$f1
[ 0-9a-f]+: 44040800 mfc1 a0,\$f1
[ 0-9a-f]+: c4610000 lwc1 \$f1,0\(v1\)
[ 0-9a-f]+: e4610000 swc1 \$f1,0\(v1\)

View File

@ -0,0 +1,5 @@
.*: Assembler messages:
.*:1: Error: float register should be even, was 1
.*:2: Error: float register should be even, was 1
.*:3: Error: float register should be even, was 1
.*:4: Error: float register should be even, was 1

Some files were not shown because too many files have changed in this diff Show More