From: Richard Sandiford Date: Fri, 19 Oct 2007 08:30:31 +0000 (+0000) Subject: mips.c (mips_output_32bit_xfer): New function. X-Git-Tag: releases/gcc-4.3.0~1936 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5b372d333746bac155f9ed14d57e2cbb93508078;p=thirdparty%2Fgcc.git mips.c (mips_output_32bit_xfer): New function. gcc/ * config/mips/mips.c (mips_output_32bit_xfer): New function. (mips_output_64bit_xfer): Likewise. (mips16_fp_args): Rename to... (mips_output_args_xfer): ...this and replace the FROM_FP_P argument with a DIRECTION argument. Use mips_output_32bit_xfer and mips_output_64bit_xfer. (build_mips16_function_stub): Update accordingly. (mips16_fpret_double): Delete. (build_mips16_call_stub): Update after above changes. Use mips_output_32bit_xfer. Use mips_output_64bit_xfer instead of mips16_fpret_double. Use GP_REG_RETURN. From-SVN: r129475 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a113b56f05aa..de27aeed8332 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2007-10-19 Richard Sandiford + + * config/mips/mips.c (mips_output_32bit_xfer): New function. + (mips_output_64bit_xfer): Likewise. + (mips16_fp_args): Rename to... + (mips_output_args_xfer): ...this and replace the FROM_FP_P argument + with a DIRECTION argument. Use mips_output_32bit_xfer and + mips_output_64bit_xfer. + (build_mips16_function_stub): Update accordingly. + (mips16_fpret_double): Delete. + (build_mips16_call_stub): Update after above changes. + Use mips_output_32bit_xfer. Use mips_output_64bit_xfer instead + of mips16_fpret_double. Use GP_REG_RETURN. + 2007-10-19 Richard Sandiford * config/mips/mips.c (mips16_fp_args): Remove the FILE argument and diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 23a318a8ca3c..21abe73b9cab 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -5067,28 +5067,57 @@ mips16_call_stub_mode_suffix (enum machine_mode mode) gcc_unreachable (); } -/* Write out code to move floating point arguments in or out of +/* Write instructions to move a 32-bit value between general register + GPREG and floating-point register FPREG. DIRECTION is 't' to move + from GPREG to FPREG and 'f' to move in the opposite direction. */ + +static void +mips_output_32bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg) +{ + fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction, + reg_names[gpreg], reg_names[fpreg]); +} + +/* Likewise for 64-bit values. */ + +static void +mips_output_64bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg) +{ + if (TARGET_64BIT) + fprintf (asm_out_file, "\tdm%cc1\t%s,%s\n", direction, + reg_names[gpreg], reg_names[fpreg]); + else if (TARGET_FLOAT64) + { + fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction, + reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]); + fprintf (asm_out_file, "\tm%chc1\t%s,%s\n", direction, + reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg]); + } + else + { + /* Move the least-significant word. */ + fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction, + reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]); + /* ...then the most significant word. */ + fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction, + reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg + 1]); + } +} + +/* Write out code to move floating-point arguments into or out of general registers. FP_CODE is the code describing which arguments - are present (see the comment at the definition of CUMULATIVE_ARGS in - mips.h). FROM_FP_P is nonzero if we are copying from the floating - point registers. */ + are present (see the comment above the definition of CUMULATIVE_ARGS + in mips.h). DIRECTION is as for mips_output_32bit_xfer. */ static void -mips16_fp_args (int fp_code, int from_fp_p) +mips_output_args_xfer (int fp_code, char direction) { - const char *s; - int gparg, fparg; - unsigned int f; + unsigned int gparg, fparg, f; CUMULATIVE_ARGS cum; /* This code only works for the original 32-bit ABI and the O64 ABI. */ gcc_assert (TARGET_OLDABI); - if (from_fp_p) - s = "mfc1"; - else - s = "mtc1"; - init_cumulative_args (&cum, NULL, NULL); for (f = (unsigned int) fp_code; f != 0; f >>= 2) @@ -5108,28 +5137,9 @@ mips16_fp_args (int fp_code, int from_fp_p) fparg = mips_arg_regno (&info, true); if (mode == SFmode) - fprintf (asm_out_file, "\t%s\t%s,%s\n", s, - reg_names[gparg], reg_names[fparg]); - else if (TARGET_64BIT) - fprintf (asm_out_file, "\td%s\t%s,%s\n", s, - reg_names[gparg], reg_names[fparg]); - else if (ISA_HAS_MXHC1) - /* -mips32r2 -mfp64 */ - fprintf (asm_out_file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", - s, - reg_names[gparg + (WORDS_BIG_ENDIAN ? 1 : 0)], - reg_names[fparg], - from_fp_p ? "mfhc1" : "mthc1", - reg_names[gparg + (WORDS_BIG_ENDIAN ? 0 : 1)], - reg_names[fparg]); - else if (TARGET_BIG_ENDIAN) - fprintf (asm_out_file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s, - reg_names[gparg], reg_names[fparg + 1], s, - reg_names[gparg + 1], reg_names[fparg]); + mips_output_32bit_xfer (direction, gparg, fparg); else - fprintf (asm_out_file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s, - reg_names[gparg], reg_names[fparg], s, - reg_names[gparg + 1], reg_names[fparg + 1]); + mips_output_64bit_xfer (direction, gparg, fparg); function_arg_advance (&cum, mode, NULL, true); } @@ -5193,7 +5203,7 @@ build_mips16_function_stub (void) /* We don't want the assembler to insert any nops here. */ fprintf (asm_out_file, "\t.set\tnoreorder\n"); - mips16_fp_args (current_function_args_info.fp_code, 1); + mips_output_args_xfer (current_function_args_info.fp_code, 'f'); fprintf (asm_out_file, "\t.set\tnoat\n"); fprintf (asm_out_file, "\tla\t%s,", reg_names[GP_REG_FIRST + 1]); @@ -5221,47 +5231,6 @@ build_mips16_function_stub (void) switch_to_section (function_section (current_function_decl)); } -/* Emit code to return a double value from a mips16 stub. GPREG is the - first GP reg to use, FPREG is the first FP reg to use. */ - -static void -mips16_fpret_double (int gpreg, int fpreg) -{ - if (TARGET_64BIT) - fprintf (asm_out_file, "\tdmfc1\t%s,%s\n", - reg_names[gpreg], reg_names[fpreg]); - else if (TARGET_FLOAT64) - { - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[gpreg + WORDS_BIG_ENDIAN], - reg_names[fpreg]); - fprintf (asm_out_file, "\tmfhc1\t%s,%s\n", - reg_names[gpreg + !WORDS_BIG_ENDIAN], - reg_names[fpreg]); - } - else - { - if (TARGET_BIG_ENDIAN) - { - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[gpreg + 0], - reg_names[fpreg + 1]); - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[gpreg + 1], - reg_names[fpreg + 0]); - } - else - { - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[gpreg + 0], - reg_names[fpreg + 0]); - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[gpreg + 1], - reg_names[fpreg + 1]); - } - } -} - /* Build a call stub for a mips16 call. A stub is needed if we are passing any floating point values which should go into the floating point registers. If we are, and the call turns out to be to a @@ -5452,7 +5421,7 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code) /* We don't want the assembler to insert any nops here. */ fprintf (asm_out_file, "\t.set\tnoreorder\n"); - mips16_fp_args (fp_code, 0); + mips_output_args_xfer (fp_code, 't'); if (! fpret) { @@ -5478,36 +5447,33 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code) switch (GET_MODE (retval)) { case SCmode: - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[GP_REG_FIRST + 3], - reg_names[FP_REG_FIRST + MAX_FPRS_PER_FMT]); + mips_output_32bit_xfer ('f', GP_RETURN + 1, + FP_REG_FIRST + MAX_FPRS_PER_FMT); /* Fall though. */ case SFmode: - fprintf (asm_out_file, "\tmfc1\t%s,%s\n", - reg_names[GP_REG_FIRST + 2], - reg_names[FP_REG_FIRST + 0]); + mips_output_32bit_xfer ('f', GP_RETURN, FP_REG_FIRST); if (GET_MODE (retval) == SCmode && TARGET_64BIT) { /* On 64-bit targets, complex floats are returned in a single GPR, such that "sd" on a suitably-aligned target would store the value correctly. */ fprintf (asm_out_file, "\tdsll\t%s,%s,32\n", - reg_names[GP_REG_FIRST + 2 + TARGET_LITTLE_ENDIAN], - reg_names[GP_REG_FIRST + 2 + TARGET_LITTLE_ENDIAN]); + reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN], + reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN]); fprintf (asm_out_file, "\tor\t%s,%s,%s\n", - reg_names[GP_REG_FIRST + 2], - reg_names[GP_REG_FIRST + 2], - reg_names[GP_REG_FIRST + 3]); + reg_names[GP_RETURN], + reg_names[GP_RETURN], + reg_names[GP_RETURN + 1]); } break; case DCmode: - mips16_fpret_double (GP_REG_FIRST + 2 + (8 / UNITS_PER_WORD), - FP_REG_FIRST + MAX_FPRS_PER_FMT); + mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD), + FP_REG_FIRST + MAX_FPRS_PER_FMT); /* Fall though. */ case DFmode: case V2SFmode: - mips16_fpret_double (GP_REG_FIRST + 2, FP_REG_FIRST + 0); + mips_output_64bit_xfer ('f', GP_RETURN, FP_REG_FIRST); break; default: