# Support for adding __float128 to the powerpc.

# The standard 128-bit floating point support functions are TFmode.  Most
# PowerPC targets use a long double format that has a pair of doubles to give
# you more precision, but no extra expoenent range.  This long double format is
# mostly compatible with the format used by the IBM XL compilers.  Some of the
# names used by the IBM double-double format use TF in them, so we rename
# all of the functions provided for the new IEEE 128-bit support.
#
# We use the TF functions in soft-fp for 128-bit floating point support, using
# sed to transform the names in the files from TF names to KF names.

# Emulator functions from the soft-fp directory
fp128_softfp_funcs	= addkf3 subkf3 mulkf3 divkf3 negkf2 \
			  unordkf2 eqkf2 gekf2 lekf2 \
			  extendsfkf2 extenddfkf2 trunckfsf2 trunckfdf2 \
			  fixkfsi fixkfdi fixunskfsi fixunskfdi \
			  floatsikf floatdikf floatunsikf floatundikf \
			  floatbitintkf fixkfbitint

fp128_softfp_src	= $(addsuffix -sw.c,$(fp128_softfp_funcs))
fp128_softfp_static_obj	= $(addsuffix -sw$(objext),$(fp128_softfp_funcs))
fp128_softfp_shared_obj	= $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs))
fp128_softfp_obj	= $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)

# Decimal <-> _Float128 conversions
fp128_dec_funcs		= _kf_to_sd _kf_to_dd _kf_to_td \
			  _sd_to_kf _dd_to_kf _td_to_kf

# Decimal <-> __ibm128 conversions
ibm128_dec_funcs	= _tf_to_sd _tf_to_dd _tf_to_td \
			  _sd_to_tf _dd_to_tf _td_to_tf


# New functions for software emulation
fp128_ppc_funcs		= floattikf-sw floatuntikf-sw \
			  fixkfti-sw fixunskfti-sw \
			  extendkftf2-sw trunctfkf2-sw \
			  sfp-exceptions _mulkc3 _divkc3 _powikf2 \

# Plain binary float/double <-> _BitInt conversions.  Unlike the DPD
# decimal set below, these are unconditional in the generic t-softfp
# mechanism (softfp_bitint_func_list): every target using t-softfp gets
# them regardless of decimal_float.  t-softfp is not in the rs6000
# tmake_file, so wire them up here directly from soft-fp/, matching the
# LIB2ADD_ST treatment in t-softfp.
rs6000_bitint_bin_funcs = fixsfbitint floatbitintsf \
			  fixdfbitint floatbitintdf

rs6000_bitint_bin_src   = $(addprefix $(srcdir)/soft-fp/, \
			  $(addsuffix .c,$(rs6000_bitint_bin_funcs)))

LIB2ADD += $(rs6000_bitint_bin_src)

ifeq ($(decimal_float),yes)
fp128_ppc_funcs        += $(fp128_dec_funcs)

# DPD _BitInt <-> decimal floating-point conversions, plus the TImode
# <-> decimal floating-point conversions _BitInt lowering depends on.
# t-softfp is not in the rs6000 tmake_file so these are never compiled
# via the generic softfp_bid_list mechanism.  Wire them up here instead,
# sourced directly from libgcc/soft-fp/ and added to LIB2ADD_ST (static
# library only), matching the LIB2ADD_ST treatment in t-softfp.
rs6000_bitint_dec_funcs = bitintpow10 \
			  fixsdbitint floatbitintsd \
                          fixsdti fixunssdti floattisd floatuntisd \
                          fixddbitint floatbitintdd \
                          fixddti fixunsddti floattidd floatuntidd \
                          fixtdbitint floatbitinttd \
                          fixtdti fixunstdti floattitd floatuntitd

rs6000_bitint_dec_src   = $(addprefix $(srcdir)/soft-fp/, \
                          $(addsuffix .c,$(rs6000_bitint_dec_funcs)))

LIB2ADD_ST += $(rs6000_bitint_dec_src)
endif

fp128_ppc_src		= $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
				.c,$(fp128_ppc_funcs)))
fp128_ppc_static_obj	= $(addsuffix $(objext),$(fp128_ppc_funcs))
fp128_ppc_shared_obj	= $(addsuffix _s$(objext),$(fp128_ppc_funcs))
fp128_ppc_obj		= $(fp128_ppc_static_obj) $(fp128_ppc_shared_obj)

# All functions
fp128_funcs		= $(fp128_softfp_funcs) $(fp128_ppc_funcs) \
			  $(fp128_hw_funcs) $(fp128_ifunc_funcs) \
			  $(fp128_3_1_hw_funcs)

fp128_src		= $(fp128_softfp_src) $(fp128_ppc_src) \
			  $(fp128_hw_src) $(fp128_ifunc_src) \
			  $(fp128_3_1_hw_src)

fp128_obj		= $(fp128_softfp_obj) $(fp128_ppc_obj) \
			  $(fp128_hw_obj) $(fp128_ifunc_obj) \
			  $(fp128_3_1_hw_obj)

fp128_sed		= $(srcdir)/config/rs6000/float128-sed$(fp128_sed_hw)
fp128_dep		= $(fp128_sed) $(srcdir)/config/rs6000/t-float128

fp128_includes		= $(srcdir)/soft-fp/double.h \
			  $(srcdir)/soft-fp/op-1.h \
			  $(srcdir)/soft-fp/op-4.h \
			  $(srcdir)/soft-fp/op-common.h \
			  $(srcdir)/soft-fp/single.h \
			  $(srcdir)/soft-fp/extended.h \
			  $(srcdir)/soft-fp/op-2.h \
			  $(srcdir)/soft-fp/op-8.h \
			  $(srcdir)/soft-fp/quad.h \
			  $(srcdir)/soft-fp/soft-fp.h

# Build the emulator without ISA 3.0 hardware support.
FP128_CFLAGS_SW		 = -Wno-type-limits -mvsx -mfloat128 \
			   -mno-float128-hardware -mno-gnu-attribute \
			   -I$(srcdir)/soft-fp \
			   -I$(srcdir)/config/rs6000 \
			   $(FLOAT128_HW_INSNS)

$(fp128_softfp_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
$(fp128_ppc_obj)	 : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
$(fp128_obj)		 : $(fp128_includes)
$(fp128_obj)		 : $(srcdir)/config/rs6000/quad-float128.h

# Force the TF mode to/from decimal functions to be compiled with IBM long
# double.  Add building the KF mode to/from decimal conversions with explict
# IEEE long double.
fp128_dec_objs		= $(addsuffix $(objext),$(fp128_dec_funcs)) \
			  $(addsuffix _s$(objext),$(fp128_dec_funcs))

ibm128_dec_objs		= $(addsuffix $(objext),$(ibm128_dec_funcs)) \
			  $(addsuffix _s$(objext),$(ibm128_dec_funcs))

FP128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
IBM128_CFLAGS_DECIMAL	= -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble

$(fp128_dec_objs)	: INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL)
$(ibm128_dec_objs)	: INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)


$(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
	@src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
	echo "Create $@"; \
	(echo "/* file created from $$src */"; \
	 echo; \
	 sed -f $(fp128_sed) < $$src) > $@

.PHONY: test clean-float128

test:
	@echo "fp128_src:"; \
	for x in $(fp128_src); do echo "    $$x"; done; \
	echo; \
	echo "fp128_obj:"; \
	for x in $(fp128_obj); do echo "    $$x"; done;

clean-float128:
	-rm -f $(fp128_softfp_src) $(fp128_hardfp_src)
	@$(MULTICLEAN) multi-clean DO=clean-float128

# For now, only put it in the static library
# LIB2ADD += $(fp128_src)

LIB2ADD_ST += $(fp128_src)
