aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorMatthew Fortune <matthew.fortune@imgtec.com>2014-11-12 21:39:46 +0000
committerMatthew Fortune <mpf@gcc.gnu.org>2014-11-12 21:39:46 +0000
commit050af1445b878d2a8a070f4c2ad602cbe80f8d73 (patch)
treeae5a1e2880c64a6507d463ca40e21b1f5abaf535 /libgcc
parent21c767169b833b6c22f8b1e8550e95ef792b6fd1 (diff)
downloadgcc-050af1445b878d2a8a070f4c2ad602cbe80f8d73.zip
gcc-050af1445b878d2a8a070f4c2ad602cbe80f8d73.tar.gz
gcc-050af1445b878d2a8a070f4c2ad602cbe80f8d73.tar.bz2
Implement MIPS o32 FPXX, FP64, FP64A ABI extensions.
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com> gcc/ * common/config/mips/mips-common.c (mips_handle_option): Ensure that -mfp32, -mfp64 disable -mfpxx and -mfpxx disables -mfp64. * config.gcc (--with-fp-32): New option. (--with-odd-spreg-32): Likewise. * config.in (HAVE_AS_DOT_MODULE): New config define. * config/mips/mips-protos.h (mips_secondary_memory_needed): New prototype. (mips_hard_regno_caller_save_mode): Likewise. * config/mips/mips.c (mips_get_reg_raw_mode): New static prototype. (mips_get_arg_info): Assert that V2SFmode is only handled specially with TARGET_PAIRED_SINGLE_FLOAT. (mips_return_mode_in_fpr_p): Likewise. (mips16_call_stub_mode_suffix): Likewise. (mips_get_reg_raw_mode): New static function. (mips_return_fpr_pair): O32 return values span two registers. (mips16_build_call_stub): Likewise. (mips_function_value_regno_p): Support both FP return registers. (mips_output_64bit_xfer): Use mthc1 whenever TARGET_HAS_MXHC1. Add specific cases for TARGET_FPXX to move via memory. (mips_dwarf_register_span): For TARGET_FPXX pretend that modes larger than UNITS_PER_FPREG 'span' one register. (mips_dwarf_frame_reg_mode): New static function. (mips_file_start): Switch to using .module instead of .gnu_attribute. No longer support FP ABI 4 (-mips32r2 -mfp64), replace with FP ABI 6. Add FP ABI 5 (-mfpxx) and FP ABI 7 (-mfp64 -mno-odd-spreg). (mips_save_reg, mips_restore_reg): Always represent DFmode frame slots with two CFI directives even for O32 FP64. (mips_for_each_saved_gpr_and_fpr): Account for fixed_regs when saving/restoring callee-saved registers. (mips_hard_regno_mode_ok_p): Implement O32 FP64A extension. (mips_secondary_memory_needed): New function. (mips_option_override): ABI check for TARGET_FLOATXX. Disable odd-numbered single-precision registers when using TARGET_FLOATXX. Implement -modd-spreg and defaults. (mips_conditional_register_usage): Redefine O32 FP64 to match O32 FP32 callee-saved behaviour. (mips_hard_regno_caller_save_mode): Implement. (TARGET_GET_RAW_RESULT_MODE): Define target hook. (TARGET_GET_RAW_ARG_MODE): Define target hook. (TARGET_DWARF_FRAME_REG_MODE): Define target hook. * config/mips/mips.h (TARGET_FLOAT32): New macro. (TARGET_O32_FP64A_ABI): Likewise. (TARGET_CPU_CPP_BUILTINS): TARGET_FPXX is __mips_fpr==0. Add _MIPS_SPFPSET builtin define. (MIPS_FPXX_OPTION_SPEC): New macro. (OPTION_DEFAULT_SPECS): Pass through --with-fp-32=* to -mfp and --with-odd-spreg-32=* to -m[no-]odd-spreg. (ISA_HAS_ODD_SPREG): New macro. (ISA_HAS_MXHC1): True for anything other than -mfp32. (ASM_SPEC): Pass through mfpxx, mfp64, -mno-odd-spreg and -modd-spreg. (MIN_FPRS_PER_FMT): Redefine in terms of TARGET_ODD_SPREG. (HARD_REGNO_CALLER_SAVE_MODE): Define. Implement O32 FPXX extension (HARD_REGNO_CALL_PART_CLOBBERED): Likewise. (SECONDARY_MEMORY_NEEDED): Likewise. (FUNCTION_ARG_REGNO_P): Update for O32 FPXX and FP64 extensions. * config/mips/mips.md (define_attr enabled): Implement O32 FPXX and FP64A ABI extensions. (move_doubleword_fpr<mode>): Use ISA_HAS_MXHC1 instead of TARGET_FLOAT64. * config/mips/mips.opt (mfpxx): New target option. (modd-spreg): Likewise. * config/mips/mti-elf.h (DRIVER_SELF_SPECS): Infer FP ABI from arch. * config/mips/mti-linux.h (DRIVER_SELF_SPECS): Likewise and remove fp64 sysroot. * config/mips/t-mti-elf: Remove fp64 multilib. * config/mips/t-mti-linux: Likewise. * configure.ac: Detect .module support. * configure: Regenerate. * doc/invoke.texi: Document -mfpxx, -modd-spreg, -mno-odd-spreg option. * doc/install.texi (--with-fp-32, --with-odd-spreg-32): Document new options. gcc/testsuite/ * gcc.target/mips/args-1.c: Handle __mips_fpr == 0. * gcc.target/mips/call-clobbered-1.c: New. * gcc.target/mips/call-clobbered-2.c: New. * gcc.target/mips/call-clobbered-3.c: New. * gcc.target/mips/call-clobbered-4.c: New. * gcc.target/mips/call-clobbered-5.c: New. * gcc.target/mips/call-saved-4.c: New. * gcc.target/mips/call-saved-5.c: New. * gcc.target/mips/call-saved-6.c: New. * gcc.target/mips/mips.exp: Support -mfpxx, -ffixed-f*, and -m[no-]odd-spreg. Use _MIPS_SPFPSET to determine default odd-spreg option. Account for -modd-spreg in minimum arch code. * gcc.target/mips/movdf-1.c: New. * gcc.target/mips/movdf-2.c: New. * gcc.target/mips/movdf-3.c: New. * gcc.target/mips/oddspreg-1.c: New. * gcc.target/mips/oddspreg-2.c: New. * gcc.target/mips/oddspreg-3.c: New. * gcc.target/mips/oddspreg-4.c: New. * gcc.target/mips/oddspreg-5.c: New. * gcc.target/mips/oddspreg-6.c: New. libgcc/ * config/mips/mips16.S: Set .module when supported. Update O32 FP64 calling convention and use for FPXX when possible. Add FPXX calling convention fallback case. From-SVN: r217446
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/config/mips/mips16.S35
2 files changed, 35 insertions, 6 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 17c8bb1..fd7ba11 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * config/mips/mips16.S: Set .module when supported. Update O32
+ FP64 calling convention and use for FPXX when possible. Add FPXX
+ calling convention fallback case.
+
2014-11-06 Bernd Schmidt <bernds@codesourcery.com>
* config.host: Handle nvptx-*-*.
diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S
index dde8939..c0c73ff 100644
--- a/libgcc/config/mips/mips16.S
+++ b/libgcc/config/mips/mips16.S
@@ -21,6 +21,8 @@ a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#include "auto-host.h"
+
#if defined(__mips_micromips) || defined(__mips_soft_float)
/* Do nothing because this code is only needed when linking
against mips16 hard-float objects. Neither micromips code
@@ -29,6 +31,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
for those cases. */
#else
+#if defined(HAVE_AS_MODULE)
+#if __mips_fpr == 32
+ .module fp=32
+#elif __mips_fpr == 0
+ .module fp=xx
+#elif __mips_fpr == 64
+ .module fp=64
+#endif
+#endif
+
/* This file contains mips16 floating point support functions. These
functions are called by mips16 code to handle floating point when
-msoft-float is not used. They accept the arguments and return
@@ -152,8 +164,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* The high 32 bits of $2 correspond to the second word in memory;
i.e. the imaginary part. */
#define MOVE_SC_RET(D, T) MERGE_GPR##D ($2, $f1, $f0); jr T
-#elif __mips_fpr == 64
-#define MOVE_SC_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f1)
#else
#define MOVE_SC_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f2)
#endif
@@ -174,16 +184,29 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define MOVE_DF_BYTE8(D) dm##D##c1 $5,$f13
#define MOVE_DF_RET(D, T) DELAY##D (T, dm##D##c1 $2,$f0)
#define MOVE_DC_RET(D, T) dm##D##c1 $3,$f1; MOVE_DF_RET (D, T)
-#elif __mips_fpr == 64 && defined(__MIPSEB__)
+#elif __mips_fpr != 32 && __mips_isa_rev >= 2 && defined(__MIPSEB__)
#define MOVE_DF_BYTE0(D) m##D##c1 $5,$f12; m##D##hc1 $4,$f12
#define MOVE_DF_BYTE8(D) m##D##c1 $7,$f14; m##D##hc1 $6,$f14
#define MOVE_DF_RET(D, T) m##D##c1 $3,$f0; DELAY##D (T, m##D##hc1 $2,$f0)
-#define MOVE_DC_RET(D, T) m##D##c1 $5,$f1; m##D##hc1 $4,$f1; MOVE_DF_RET (D, T)
-#elif __mips_fpr == 64
+#define MOVE_DC_RET(D, T) m##D##c1 $5,$f2; m##D##hc1 $4,$f2; MOVE_DF_RET (D, T)
+#elif __mips_fpr != 32 && __mips_isa_rev >= 2
#define MOVE_DF_BYTE0(D) m##D##c1 $4,$f12; m##D##hc1 $5,$f12
#define MOVE_DF_BYTE8(D) m##D##c1 $6,$f14; m##D##hc1 $7,$f14
#define MOVE_DF_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##hc1 $3,$f0)
-#define MOVE_DC_RET(D, T) m##D##c1 $4,$f1; m##D##hc1 $5,$f1; MOVE_DF_RET (D, T)
+#define MOVE_DC_RET(D, T) m##D##c1 $4,$f2; m##D##hc1 $5,$f2; MOVE_DF_RET (D, T)
+#elif __mips_fpr == 0
+#define MOVE_DF_BYTE0t sw $4, 0($29); sw $5, 4($29); ldc1 $f12, 0($29)
+#define MOVE_DF_BYTE0f sdc1 $f12, 0($29); lw $4, 0($29); lw $5, 4($29)
+#define MOVE_DF_BYTE0(D) MOVE_DF_BYTE0##D
+#define MOVE_DF_BYTE8t sw $6, 8($29); sw $7, 12($29); ldc1 $f14, 8($29)
+#define MOVE_DF_BYTE8f sdc1 $f14, 8($29); lw $6, 8($29); lw $7, 12($29)
+#define MOVE_DF_BYTE8(D) MOVE_DF_BYTE8##D
+#define MOVE_DF_RETt(T) sw $2, 0($29); sw $3, 4($29); DELAYt (T, ldc1 $f0, 0($29))
+#define MOVE_DF_RETf(T) sdc1 $f0, 0($29); lw $2, 0($29); DELAYf (T, lw $3, 4($29))
+#define MOVE_DF_RET(D, T) MOVE_DF_RET##D(T)
+#define MOVE_DC_RETt(T) sw $4, 8($29); sw $5, 12($29); ldc1 $f2, 8($29); MOVE_DF_RETt(T)
+#define MOVE_DC_RETf(T) sdc1 $f2, 8($29); lw $4, 8($29); lw $5, 12($29); MOVE_DF_RETf(T)
+#define MOVE_DC_RET(D, T) MOVE_DF_RET##D(T)
#elif defined(__MIPSEB__)
/* FPRs are little-endian. */
#define MOVE_DF_BYTE0(D) m##D##c1 $4,$f13; m##D##c1 $5,$f12