Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Commit

Permalink
Set long double to 128 bit for RV64
Browse files Browse the repository at this point in the history
 - Use softfp instead of *PBITS
 - Remove riscv-fp.c.
 - long double and struct {long double} always pass in memory.
  • Loading branch information
kito-cheng authored and aswaterman committed Oct 25, 2016
1 parent 254d044 commit 54b21fc
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 193 deletions.
22 changes: 22 additions & 0 deletions gcc/config/riscv/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2554,6 +2554,23 @@ riscv_function_value (const_tree valtype, const_tree func, enum machine_mode mod
static bool
riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
{
/* TFmode alwyas pass by reference. */
if (TYPE_MODE (type) == TFmode)
{
return true;
}

if (TREE_CODE (type) == RECORD_TYPE)
{
tree field;
/* Check if this struc only TFmode, then it's still pass in memory. */
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL
&& !error_operand_p (field)
&& TYPE_MODE (TREE_TYPE (field)) == TFmode)
return true;
}

return !IN_RANGE (int_size_in_bytes (type), 0, 2 * UNITS_PER_WORD);
}

Expand All @@ -2564,6 +2581,11 @@ riscv_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
enum machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{
/* TFmode alwyas pass by reference. */
if (mode == TFmode)
{
return true;
}
if (type && riscv_return_in_memory (type, NULL_TREE))
return true;
return targetm.calls.must_pass_in_stack (mode, type);
Expand Down
3 changes: 1 addition & 2 deletions gcc/config/riscv/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,7 @@ along with GCC; see the file COPYING3. If not see

#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
/* XXX The ABI says long doubles are IEEE-754-2008 float128s. */
#define LONG_DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE (TARGET_64BIT ? 128 : 64)

#ifdef IN_LIBGCC2
# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
Expand Down
4 changes: 2 additions & 2 deletions libgcc/config.host
Original file line number Diff line number Diff line change
Expand Up @@ -1097,11 +1097,11 @@ powerpcle-*-eabi*)
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
riscv*-*-linux*)
tmake_file="${tmake_file} riscv/t-elf riscv/t-elf${host_address}"
tmake_file="${tmake_file} t-softfp-sfdf riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}"
extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o"
;;
riscv*-*-*)
tmake_file="${tmake_file} riscv/t-elf riscv/t-elf${host_address}"
tmake_file="${tmake_file} t-softfp-sfdf riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}"
extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o"
;;
rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
Expand Down
178 changes: 0 additions & 178 deletions libgcc/config/riscv/riscv-fp.c

This file was deleted.

100 changes: 100 additions & 0 deletions libgcc/config/riscv/sfp-machine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@

#ifdef __riscv32

#define _FP_W_TYPE_SIZE 32
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
#define _FP_I_TYPE long

#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)

#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)

#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1

#else

#define _FP_W_TYPE_SIZE 64
#define _FP_W_TYPE unsigned long long
#define _FP_WS_TYPE signed long long
#define _FP_I_TYPE long long

#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)

#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)

#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1

#endif

#ifdef __riscv64
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
#endif

/* The type of the result of a floating point comparison. This must
match __libgcc_cmp_return__ in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype

#define _FP_NANSIGN_S 0
#define _FP_NANSIGN_D 0
#define _FP_NANSIGN_Q 0

#define _FP_KEEPNANFRACP 1
#define _FP_QNANNEGATEDP 0


/* From my experiments it seems X is chosen unless one of the
NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(X) | \
_FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs) \
{ \
R##_s = _FP_NANSIGN_##fs; \
_FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \
} \
else \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
R##_c = FP_CLS_NAN; \
} while (0)

#define _FP_TININESS_AFTER_ROUNDING 0

#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321

#if defined __big_endian__
# define __BYTE_ORDER __BIG_ENDIAN
#else
# define __BYTE_ORDER __LITTLE_ENDIAN
#endif


/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
12 changes: 1 addition & 11 deletions libgcc/config/riscv/t-elf
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
LIB2ADD += $(srcdir)/config/riscv/riscv-fp.c \
$(srcdir)/config/riscv/save-restore.S \
LIB2ADD += $(srcdir)/config/riscv/save-restore.S \
$(srcdir)/config/riscv/muldi3.S \
$(srcdir)/config/riscv/multi3.S \
$(srcdir)/config/riscv/div.S \
$(srcdir)/config/riscv/atomic.c \

FPBIT = true

ifeq ($(double_type_size),64)
DPBIT = true
endif

ifeq ($(long_double_type_size),128)
TPBIT = true
endif
Empty file added libgcc/config/riscv/t-softfp32
Empty file.
4 changes: 4 additions & 0 deletions libgcc/config/riscv/t-softfp64
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
softfp_float_modes += tf
softfp_int_modes += ti
softfp_extensions += sftf dftf
softfp_truncations += tfsf tfdf

0 comments on commit 54b21fc

Please sign in to comment.