Commit aa221564 by Sandra Loosemore Committed by Sandra Loosemore

nios2.md (UNSPEC_ROUND): New.

2014-04-22  Sandra Loosemore  <sandra@codesourcery.com>

	gcc/
	* config/nios2/nios2.md (UNSPEC_ROUND): New.
	(lroundsfsi2): New.
	* config/nios2/nios2.opt (mno-custom-round, mcustom-round=): New.
	* config/nios2/nios2-opts.h (N2FPU_ALL_CODES): Add round.
	* config/nios2/nios2.c (N2F_NO_ERRNO): Define.
	(nios2_fpu_insn): Add entry for round.
	(N2FPU_NO_ERRNO_P): Define.
	(nios2_custom_check_insns): Add check for N2F_NO_ERRNO and
	flag_errno_math.
	* doc/invoke.texi (Nios II Options): Document -mcustom-round.

	gcc/testsuite/
	* gcc.target/nios2/custom-fp-conversion.c: Adjust to test that
	lroundf generates custom round instruction, too.

From-SVN: r209670
parent 5f056aaa
2014-04-22 Sandra Loosemore <sandra@codesourcery.com>
* config/nios2/nios2.md (UNSPEC_ROUND): New.
(lroundsfsi2): New.
* config/nios2/nios2.opt (mno-custom-round, mcustom-round=): New.
* config/nios2/nios2-opts.h (N2FPU_ALL_CODES): Add round.
* config/nios2/nios2.c (N2F_NO_ERRNO): Define.
(nios2_fpu_insn): Add entry for round.
(N2FPU_NO_ERRNO_P): Define.
(nios2_custom_check_insns): Add check for N2F_NO_ERRNO and
flag_errno_math.
* doc/invoke.texi (Nios II Options): Document -mcustom-round.
2014-04-22 Richard Henderson <rth@redhat.com> 2014-04-22 Richard Henderson <rth@redhat.com>
* config/aarch64/aarch64 (addti3, subti3): New expanders. * config/aarch64/aarch64 (addti3, subti3): New expanders.
......
...@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
\ \
N2FPU_CODE(floatis) N2FPU_CODE(floatus) \ N2FPU_CODE(floatis) N2FPU_CODE(floatus) \
N2FPU_CODE(floatid) N2FPU_CODE(floatud) \ N2FPU_CODE(floatid) N2FPU_CODE(floatud) \
N2FPU_CODE(fixsi) N2FPU_CODE(fixsu) \ N2FPU_CODE(round) N2FPU_CODE(fixsi) N2FPU_CODE(fixsu) \
N2FPU_CODE(fixdi) N2FPU_CODE(fixdu) \ N2FPU_CODE(fixdi) N2FPU_CODE(fixdu) \
N2FPU_CODE(fextsd) N2FPU_CODE(ftruncds) \ N2FPU_CODE(fextsd) N2FPU_CODE(ftruncds) \
\ \
......
...@@ -192,6 +192,7 @@ struct nios2_fpu_insn_info ...@@ -192,6 +192,7 @@ struct nios2_fpu_insn_info
#define N2F_DFREQ 0x2 #define N2F_DFREQ 0x2
#define N2F_UNSAFE 0x4 #define N2F_UNSAFE 0x4
#define N2F_FINITE 0x8 #define N2F_FINITE 0x8
#define N2F_NO_ERRNO 0x10
unsigned int flags; unsigned int flags;
enum insn_code icode; enum insn_code icode;
enum nios2_ftcode ftcode; enum nios2_ftcode ftcode;
...@@ -274,6 +275,7 @@ struct nios2_fpu_insn_info nios2_fpu_insn[] = ...@@ -274,6 +275,7 @@ struct nios2_fpu_insn_info nios2_fpu_insn[] =
N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)), N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)),
N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)), N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)),
N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)), N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)),
N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)),
N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)), N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)),
N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)), N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)),
N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)), N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)),
...@@ -298,6 +300,7 @@ struct nios2_fpu_insn_info nios2_fpu_insn[] = ...@@ -298,6 +300,7 @@ struct nios2_fpu_insn_info nios2_fpu_insn[] =
#define N2FPU_FTCODE(code) (N2FPU(code).ftcode) #define N2FPU_FTCODE(code) (N2FPU(code).ftcode)
#define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE) #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE)
#define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE) #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE)
#define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO)
#define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF) #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
#define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ) #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
...@@ -844,6 +847,15 @@ nios2_custom_check_insns (void) ...@@ -844,6 +847,15 @@ nios2_custom_check_insns (void)
warning (0, "switch %<-mcustom-%s%> has no effect unless " warning (0, "switch %<-mcustom-%s%> has no effect unless "
"-ffinite-math-only is specified", N2FPU_NAME (i)); "-ffinite-math-only is specified", N2FPU_NAME (i));
/* Warn if the user is trying to use a custom rounding instruction
that won't get used without -fno-math-errno. See
expand_builtin_int_roundingfn_2 () in builtins.c. */
if (flag_errno_math)
for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
warning (0, "switch %<-mcustom-%s%> has no effect unless "
"-fno-math-errno is specified", N2FPU_NAME (i));
if (errors || custom_code_conflict) if (errors || custom_code_conflict)
fatal_error ("conflicting use of -mcustom switches, target attributes, " fatal_error ("conflicting use of -mcustom switches, target attributes, "
"and/or __builtin_custom_ functions"); "and/or __builtin_custom_ functions");
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
UNSPEC_FATAN UNSPEC_FATAN
UNSPEC_FEXP UNSPEC_FEXP
UNSPEC_FLOG UNSPEC_FLOG
UNSPEC_ROUND
UNSPEC_LOAD_GOT_REGISTER UNSPEC_LOAD_GOT_REGISTER
UNSPEC_PIC_SYM UNSPEC_PIC_SYM
UNSPEC_PIC_CALL_SYM UNSPEC_PIC_CALL_SYM
...@@ -585,6 +586,13 @@ ...@@ -585,6 +586,13 @@
{ return nios2_fpu_insn_asm (n2fpu_fix<f><i>); } { return nios2_fpu_insn_asm (n2fpu_fix<f><i>); }
[(set_attr "type" "custom")]) [(set_attr "type" "custom")])
(define_insn "lroundsfsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SF 1 "general_operand" "r")] UNSPEC_ROUND))]
"nios2_fpu_insn_enabled (n2fpu_round)"
{ return nios2_fpu_insn_asm (n2fpu_round); }
[(set_attr "type" "custom")])
(define_insn "extendsfdf2" (define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=r") [(set (match_operand:DF 0 "register_operand" "=r")
(float_extend:DF (match_operand:SF 1 "general_operand" "r")))] (float_extend:DF (match_operand:SF 1 "general_operand" "r")))]
......
...@@ -529,3 +529,13 @@ Do not use the fwrx custom instruction ...@@ -529,3 +529,13 @@ Do not use the fwrx custom instruction
mcustom-fwrx= mcustom-fwrx=
Target Report RejectNegative Joined UInteger Var(nios2_custom_fwrx) Init(-1) Target Report RejectNegative Joined UInteger Var(nios2_custom_fwrx) Init(-1)
Integer id (N) of fwrx custom instruction Integer id (N) of fwrx custom instruction
mno-custom-round
Target Report RejectNegative Var(nios2_custom_round, -1)
Do not use the round custom instruction
mcustom-round=
Target Report RejectNegative Joined UInteger Var(nios2_custom_round) Init(-1)
Integer id (N) of round custom instruction
...@@ -18485,6 +18485,12 @@ Conversion from double precision to single precision. ...@@ -18485,6 +18485,12 @@ Conversion from double precision to single precision.
Conversion from floating point to signed or unsigned integer types, with Conversion from floating point to signed or unsigned integer types, with
truncation towards zero. truncation towards zero.
@item @samp{round}
Conversion from single-precision floating point to signed integer,
rounding to the nearest integer and ties away from zero.
This corresponds to the @code{__builtin_lroundf} function when
@option{-fno-math-errno} is used.
@item @samp{floatis}, @samp{floatus}, @samp{floatid}, @samp{floatud} @item @samp{floatis}, @samp{floatus}, @samp{floatid}, @samp{floatud}
Conversion from signed or unsigned integer types to floating-point types. Conversion from signed or unsigned integer types to floating-point types.
......
2014-04-22 Sandra Loosemore <sandra@codesourcery.com>
* gcc.target/nios2/custom-fp-conversion.c: Adjust to test that
lroundf generates custom round instruction, too.
2014-04-22 Tobias Burnus <burnus@net-b.de> 2014-04-22 Tobias Burnus <burnus@net-b.de>
PR fortran/60881 PR fortran/60881
......
/* Test generation of conversion custom instructions. */ /* Test generation of conversion custom instructions. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O1 -ffinite-math-only -funsafe-math-optimizations" } */ /* { dg-options "-O1 -ffinite-math-only -funsafe-math-optimizations -fno-math-errno" } */
/* -O1 in the options is significant. Without it FP operations may not be /* -O1 in the options is significant. Without it FP operations may not be
optimized to custom instructions. */ optimized to custom instructions. Also, -fno-math-errno is required
to inline lroundf. */
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
...@@ -25,6 +26,8 @@ ...@@ -25,6 +26,8 @@
#pragma GCC target ("custom-floatud=107") #pragma GCC target ("custom-floatud=107")
#pragma GCC target ("custom-floatus=108") #pragma GCC target ("custom-floatus=108")
#pragma GCC target ("custom-ftruncds=109") #pragma GCC target ("custom-ftruncds=109")
#pragma GCC target ("custom-round=110")
typedef struct data { typedef struct data {
double fextsd; double fextsd;
...@@ -37,6 +40,7 @@ typedef struct data { ...@@ -37,6 +40,7 @@ typedef struct data {
double floatud; double floatud;
float floatus; float floatus;
float ftruncds; float ftruncds;
int round;
} data_t; } data_t;
void void
...@@ -52,6 +56,7 @@ custom_fp (int i, unsigned u, float f, double d, data_t *out) ...@@ -52,6 +56,7 @@ custom_fp (int i, unsigned u, float f, double d, data_t *out)
out->floatud = (double) u; out->floatud = (double) u;
out->floatus = (float) u; out->floatus = (float) u;
out->ftruncds = (float) d; out->ftruncds = (float) d;
out->round = lroundf (f);
} }
/* { dg-final { scan-assembler "custom\\t100, .* # fextsd .*" } } */ /* { dg-final { scan-assembler "custom\\t100, .* # fextsd .*" } } */
...@@ -64,3 +69,4 @@ custom_fp (int i, unsigned u, float f, double d, data_t *out) ...@@ -64,3 +69,4 @@ custom_fp (int i, unsigned u, float f, double d, data_t *out)
/* { dg-final { scan-assembler "custom\\t107, .* # floatud .*" } } */ /* { dg-final { scan-assembler "custom\\t107, .* # floatud .*" } } */
/* { dg-final { scan-assembler "custom\\t108, .* # floatus .*" } } */ /* { dg-final { scan-assembler "custom\\t108, .* # floatus .*" } } */
/* { dg-final { scan-assembler "custom\\t109, .* # ftruncds .*" } } */ /* { dg-final { scan-assembler "custom\\t109, .* # ftruncds .*" } } */
/* { dg-final { scan-assembler "custom\\t110, .* # round .*" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment