[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:
parent
7e09a22367
commit
351cdf24d2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
792
bfd/elfxx-mips.c
792
bfd/elfxx-mips.c
|
@ -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 (®info, 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
#...
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,0
|
|
@ -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'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,1
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,1 is incompatible with `gp=32 fp=64'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,1
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,1
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,1 is incompatible with `singlefloat'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,1
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,1 is incompatible with `softfloat'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,1
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,1
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,2 requires `singlefloat'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,2
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,2 is incompatible with `softfloat'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,2
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,2
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,3 requires `softfloat'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,3
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,3
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,4 is no longer supported
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,4
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,5 requires `-mabi=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,5
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,5 requires `fp=xx'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,5
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 requires `-mabi=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 is incompatible with `nooddspreg'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 requires `fp=64'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,7 requires `-mabi=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,7
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,6 is incompatible with `fp=32'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,6
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,7 requires `nooddspreg'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,7
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*: Warning: .gnu_attribute 4,7 requires `fp=64'
|
|
@ -0,0 +1 @@
|
|||
.gnu_attribute 4,7
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
#...
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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\)
|
|
@ -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
Loading…
Reference in New Issue