* libfuncs.h (LTI_extendsfdf2, LTI_extendsfxf2, LTI_extendsftf2)

(LTI_extenddfxf2, LTI_extenddftf2, LTI_truncdfsf2, LTI_truncxfsf2)
	(LTI_trunctfsf2, LTI_truncxfdf2, LTI_trunctfdf2, LTI_floatsisf)
	(LTI_floatdisf, LTI_floattisf, LTI_floatsidf, LTI_floatdidf)
	(LTI_floattidf, LTI_floatsixf, LTI_floatdixf, LTI_floattixf)
	(LTI_floatsitf, LTI_floatditf, LTI_floattitf, LTI_fixsfsi, LTI_fixsfdi)
	(LTI_fixsfti, LTI_fixdfsi, LTI_fixdfdi, LTI_fixdfti, LTI_fixxfsi)
	(LTI_fixxfdi, LTI_fixxfti, LTI_fixtfsi, LTI_fixtfdi, LTI_fixtfti)
	(LTI_fixunssfsi, LTI_fixunssfdi, LTI_fixunssfti, LTI_fixunsdfsi)
	(LTI_fixunsdfdi, LTI_fixunsdfti, LTI_fixunsxfsi, LTI_fixunsxfdi)
	(LTI_fixunsxfti, LTI_fixunstfsi, LTI_fixunstfdi, LTI_fixunstfti)
	(extendsfdf2_libfunc, extendsfxf2_libfunc, extendsftf2_libfunc)
	(extenddfxf2_libfunc, extenddftf2_libfunc, truncdfsf2_libfunc)
	(truncxfsf2_libfunc, trunctfsf2_libfunc, truncxfdf2_libfunc)
	(trunctfdf2_libfunc, floatsisf_libfunc, floatdisf_libfunc)
	(floattisf_libfunc, floatsidf_libfunc, floatdidf_libfunc)
	(floattidf_libfunc, floatsixf_libfunc, floatdixf_libfunc)
	(floattixf_libfunc, floatsitf_libfunc, floatditf_libfunc)
	(floattitf_libfunc, fixsfsi_libfunc, fixsfdi_libfunc, fixsfti_libfunc)
	(fixdfsi_libfunc, fixdfdi_libfunc, fixdfti_libfunc, fixxfsi_libfunc)
	(fixxfdi_libfunc, fixxfti_libfunc, fixtfsi_libfunc, fixtfdi_libfunc)
	(fixtfti_libfunc, fixunssfsi_libfunc, fixunssfdi_libfunc)
	(fixunssfti_libfunc, fixunsdfsi_libfunc, fixunsdfdi_libfunc)
	(fixunsdfti_libfunc, fixunsxfsi_libfunc, fixunsxfdi_libfunc)
	(fixunsxfti_libfunc, fixunstfsi_libfunc, fixunstfdi_libfunc)
	(fixunstfti_libfunc): Delete.
	* optabs.h (struct optab_handlers): Break out of struct optab.
	(struct convert_optab, convert_optab, enum convert_optab_index,
	convert_optab_table, sext_optab, zext_optab, trunc_optab,
	sfix_optab, ufix_optab, sfixtrunc_optab, ufixtrunc_optab,
	sfloat_optab, ufloat_optab): New.
	(set_conv_libfunc): Prototype.
	(GEN_FCN): Use C90 indirect call syntax, remove unnecessary cast.
	(trunc_optab): Renamed btrunc_optab.
	* builtins.c (expand_builtin_mathfn): Update to match.
	* optabs.c (extendtab, fixtab, fixtrunctab, floattab): Delete.
	(convert_optab_table, new_convert_optab, init_convert_optab)
	(init_interclass_conv_libfuncs, init_intraclass_conv_libfuncs)
	(set_conv_libfunc): New.
	(can_extend_p, gen_extend_insn, can_fix_p, can_float_p)
	(expand_float, expand_fix): Use new conversion optabs,
	not old insn code tables or long chains of ifs.
	(init_optabs): No need to clear old insn code tables.
	Initialize the new optabs, not the old libfunc array entries.
	Don't handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
	* genopinit.c: Initialize conversion optabs, not the
	former insn code tables.  Remove unnecessary casts.
	Handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
	* expr.c (convert_move): Remove redundant check that
	to_real==from_real.  Use the conversion optabs instead
	of long chains of tests of modes.  Move partial-integer-mode
	interconversion above all integer conversion.  Do not recurse
	on a value forced into a register in the original mode.

	* config/gofast.h, config/frv/frv.c, config/ia64/ia64.c
	* config/mips/mips.c, config/pa/pa.c, config/rs6000/rs6000.c
	* config/sparc/sparc.c: Use set_conv_libfunc to adjust entries
	in new conversion optabs; do not reference the old libfunc
	array entries.  No need to include libfuncs.h.

From-SVN: r72178
This commit is contained in:
Zack Weinberg 2003-10-07 02:23:42 +00:00
parent 1f1dc5bb85
commit 85363ca094
14 changed files with 522 additions and 928 deletions

View File

@ -1,3 +1,65 @@
2003-10-06 Zack Weinberg <zack@codesourcery.com>
* libfuncs.h (LTI_extendsfdf2, LTI_extendsfxf2, LTI_extendsftf2)
(LTI_extenddfxf2, LTI_extenddftf2, LTI_truncdfsf2, LTI_truncxfsf2)
(LTI_trunctfsf2, LTI_truncxfdf2, LTI_trunctfdf2, LTI_floatsisf)
(LTI_floatdisf, LTI_floattisf, LTI_floatsidf, LTI_floatdidf)
(LTI_floattidf, LTI_floatsixf, LTI_floatdixf, LTI_floattixf)
(LTI_floatsitf, LTI_floatditf, LTI_floattitf, LTI_fixsfsi, LTI_fixsfdi)
(LTI_fixsfti, LTI_fixdfsi, LTI_fixdfdi, LTI_fixdfti, LTI_fixxfsi)
(LTI_fixxfdi, LTI_fixxfti, LTI_fixtfsi, LTI_fixtfdi, LTI_fixtfti)
(LTI_fixunssfsi, LTI_fixunssfdi, LTI_fixunssfti, LTI_fixunsdfsi)
(LTI_fixunsdfdi, LTI_fixunsdfti, LTI_fixunsxfsi, LTI_fixunsxfdi)
(LTI_fixunsxfti, LTI_fixunstfsi, LTI_fixunstfdi, LTI_fixunstfti)
(extendsfdf2_libfunc, extendsfxf2_libfunc, extendsftf2_libfunc)
(extenddfxf2_libfunc, extenddftf2_libfunc, truncdfsf2_libfunc)
(truncxfsf2_libfunc, trunctfsf2_libfunc, truncxfdf2_libfunc)
(trunctfdf2_libfunc, floatsisf_libfunc, floatdisf_libfunc)
(floattisf_libfunc, floatsidf_libfunc, floatdidf_libfunc)
(floattidf_libfunc, floatsixf_libfunc, floatdixf_libfunc)
(floattixf_libfunc, floatsitf_libfunc, floatditf_libfunc)
(floattitf_libfunc, fixsfsi_libfunc, fixsfdi_libfunc, fixsfti_libfunc)
(fixdfsi_libfunc, fixdfdi_libfunc, fixdfti_libfunc, fixxfsi_libfunc)
(fixxfdi_libfunc, fixxfti_libfunc, fixtfsi_libfunc, fixtfdi_libfunc)
(fixtfti_libfunc, fixunssfsi_libfunc, fixunssfdi_libfunc)
(fixunssfti_libfunc, fixunsdfsi_libfunc, fixunsdfdi_libfunc)
(fixunsdfti_libfunc, fixunsxfsi_libfunc, fixunsxfdi_libfunc)
(fixunsxfti_libfunc, fixunstfsi_libfunc, fixunstfdi_libfunc)
(fixunstfti_libfunc): Delete.
* optabs.h (struct optab_handlers): Break out of struct optab.
(struct convert_optab, convert_optab, enum convert_optab_index,
convert_optab_table, sext_optab, zext_optab, trunc_optab,
sfix_optab, ufix_optab, sfixtrunc_optab, ufixtrunc_optab,
sfloat_optab, ufloat_optab): New.
(set_conv_libfunc): Prototype.
(GEN_FCN): Use C90 indirect call syntax, remove unnecessary cast.
(trunc_optab): Renamed btrunc_optab.
* builtins.c (expand_builtin_mathfn): Update to match.
* optabs.c (extendtab, fixtab, fixtrunctab, floattab): Delete.
(convert_optab_table, new_convert_optab, init_convert_optab)
(init_interclass_conv_libfuncs, init_intraclass_conv_libfuncs)
(set_conv_libfunc): New.
(can_extend_p, gen_extend_insn, can_fix_p, can_float_p)
(expand_float, expand_fix): Use new conversion optabs,
not old insn code tables or long chains of ifs.
(init_optabs): No need to clear old insn code tables.
Initialize the new optabs, not the old libfunc array entries.
Don't handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
* genopinit.c: Initialize conversion optabs, not the
former insn code tables. Remove unnecessary casts.
Handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
* expr.c (convert_move): Remove redundant check that
to_real==from_real. Use the conversion optabs instead
of long chains of tests of modes. Move partial-integer-mode
interconversion above all integer conversion. Do not recurse
on a value forced into a register in the original mode.
* config/gofast.h, config/frv/frv.c, config/ia64/ia64.c
* config/mips/mips.c, config/pa/pa.c, config/rs6000/rs6000.c
* config/sparc/sparc.c: Use set_conv_libfunc to adjust entries
in new conversion optabs; do not reference the old libfunc
array entries. No need to include libfuncs.h.
2003-10-06 Roger Sayle <roger@eyesopen.com>
* config/i386/i386.c (ix86_expand_setcc): Annotate the floating
@ -18,9 +80,9 @@
2003-10-06 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
PR optimization/11974
* optabs.c (expand_unop): Promote libcall outmode according to
hard_libcall_value.
PR optimization/11974
* optabs.c (expand_unop): Promote libcall outmode according to
hard_libcall_value.
2003-10-06 Zack Weinberg <zack@codesourcery.com>

View File

@ -1652,7 +1652,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
case BUILT_IN_TRUNC:
case BUILT_IN_TRUNCF:
case BUILT_IN_TRUNCL:
builtin_optab = trunc_optab; break;
builtin_optab = btrunc_optab; break;
case BUILT_IN_ROUND:
case BUILT_IN_ROUNDF:
case BUILT_IN_ROUNDL:

View File

@ -40,7 +40,6 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "function.h"
#include "optabs.h"
#include "libfuncs.h"
#include "toplev.h"
#include "basic-block.h"
#include "tm_p.h"
@ -9145,20 +9144,23 @@ frv_init_libfuncs (void)
set_optab_libfunc (smul_optab, DFmode, "__muld");
set_optab_libfunc (sdiv_optab, DFmode, "__divd");
fixsfsi_libfunc = init_one_libfunc ("__ftoi");
fixunssfsi_libfunc = init_one_libfunc ("__ftoui");
fixsfdi_libfunc = init_one_libfunc ("__ftoll");
fixunssfdi_libfunc = init_one_libfunc ("__ftoull");
fixdfsi_libfunc = init_one_libfunc ("__dtoi");
fixunsdfsi_libfunc = init_one_libfunc ("__dtoui");
fixdfdi_libfunc = init_one_libfunc ("__dtoll");
fixunsdfdi_libfunc = init_one_libfunc ("__dtoull");
floatsisf_libfunc = init_one_libfunc ("__itof");
floatdisf_libfunc = init_one_libfunc ("__lltof");
floatsidf_libfunc = init_one_libfunc ("__itod");
floatdidf_libfunc = init_one_libfunc ("__lltod");
extendsfdf2_libfunc = init_one_libfunc ("__ftod");
truncdfsf2_libfunc = init_one_libfunc ("__dtof");
set_conv_libfunc (sext_optab, DFmode, SFmode, "__ftod");
set_conv_libfunc (trunc_optab, SFmode, DFmode, "__dtof");
set_conv_libfunc (sfix_optab, SImode, SFmode, "__ftoi");
set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
set_conv_libfunc (sfix_optab, SImode, DFmode, "__dtoi");
set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
set_conv_libfunc (ufix_optab, SImode, SFmode, "__ftoui");
set_conv_libfunc (ufix_optab, SImode, SFmode, "__ftoull");
set_conv_libfunc (ufix_optab, SImode, SFmode, "__dtoui");
set_conv_libfunc (ufix_optab, SImode, SFmode, "__dtoull");
set_conv_libfunc (sfloat_optab, SFmode, SImode, "__itof");
set_conv_libfunc (sfloat_optab, SFmode, DImode, "__lltof");
set_conv_libfunc (sfloat_optab, DFmode, SImode, "__itod");
set_conv_libfunc (sfloat_optab, DFmode, DImode, "__lltod");
}
/* Convert an integer constant to an accumulator register. ICODE is the

View File

@ -66,14 +66,15 @@ gofast_maybe_init_libfuncs (void)
set_optab_libfunc (lt_optab, DFmode, "dpcmp");
set_optab_libfunc (le_optab, DFmode, "dpcmp");
extendsfdf2_libfunc = init_one_libfunc ("fptodp");
truncdfsf2_libfunc = init_one_libfunc ("dptofp");
set_conv_libfunc (sext_optab, DFmode, SFmode, "fptodp");
set_conv_libfunc (trunc_optab, SFmode, DFmode, "dptofp");
floatsisf_libfunc = init_one_libfunc ("sitofp");
floatsidf_libfunc = init_one_libfunc ("litodp");
fixsfsi_libfunc = init_one_libfunc ("fptosi");
fixdfsi_libfunc = init_one_libfunc ("dptoli");
fixunssfsi_libfunc = init_one_libfunc ("fptoui");
fixunsdfsi_libfunc = init_one_libfunc ("dptoul");
set_conv_libfunc (sfix_optab, SImode, SFmode, "fptosi");
set_conv_libfunc (sfix_optab, SImode, DFmode, "dptoli");
set_conv_libfunc (ufix_optab, SImode, SFmode, "fptoui");
set_conv_libfunc (ufix_optab, SImode, DFmode, "dptoul");
set_conv_libfunc (sfloat_optab, SFmode, SImode, "sitofp");
set_conv_libfunc (sfloat_optab, DFmode, DImode, "litodp");
#endif
}

View File

@ -37,7 +37,6 @@ Boston, MA 02111-1307, USA. */
#include "recog.h"
#include "expr.h"
#include "optabs.h"
#include "libfuncs.h"
#include "except.h"
#include "function.h"
#include "ggc.h"
@ -8327,16 +8326,18 @@ ia64_hpux_init_libfuncs (void)
set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
extendsftf2_libfunc = init_one_libfunc ("_U_Qfcnvff_sgl_to_quad");
extenddftf2_libfunc = init_one_libfunc ("_U_Qfcnvff_dbl_to_quad");
trunctfsf2_libfunc = init_one_libfunc ("_U_Qfcnvff_quad_to_sgl");
trunctfdf2_libfunc = init_one_libfunc ("_U_Qfcnvff_quad_to_dbl");
floatsitf_libfunc = init_one_libfunc ("_U_Qfcnvxf_sgl_to_quad");
floatditf_libfunc = init_one_libfunc ("_U_Qfcnvxf_dbl_to_quad");
fixtfsi_libfunc = init_one_libfunc ("_U_Qfcnvfxt_quad_to_sgl");
fixtfdi_libfunc = init_one_libfunc ("_U_Qfcnvfxt_quad_to_dbl");
fixunstfsi_libfunc = init_one_libfunc ("_U_Qfcnvfxut_quad_to_sgl");
fixunstfdi_libfunc = init_one_libfunc ("_U_Qfcnvfxut_quad_to_dbl");
set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
set_conv_libfunc (ufix_optab, SImode, TFmode, "_U_Qfcnvfxut_quad_to_sgl");
set_conv_libfunc (ufix_optab, DImode, TFmode, "_U_Qfcnvfxut_quad_to_dbl");
set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
}
/* Switch to the section to which we should output X. The only thing

View File

@ -42,7 +42,6 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "expr.h"
#include "optabs.h"
#include "libfuncs.h"
#include "flags.h"
#include "reload.h"
#include "tm_p.h"
@ -9043,8 +9042,8 @@ mips_init_libfuncs (void)
set_optab_libfunc (lt_optab, SFmode, "__mips16_ltsf2");
set_optab_libfunc (le_optab, SFmode, "__mips16_lesf2");
floatsisf_libfunc = init_one_libfunc ("__mips16_floatsisf");
fixsfsi_libfunc = init_one_libfunc ("__mips16_fixsfsi");
set_conv_libfunc (sfix_optab, SImode, SFmode, "__mips16_fixsfsi");
set_conv_libfunc (sfloat_optab, SFmode, SImode, "__mips16_floatsisf");
if (TARGET_DOUBLE_FLOAT)
{
@ -9060,11 +9059,11 @@ mips_init_libfuncs (void)
set_optab_libfunc (lt_optab, DFmode, "__mips16_ltdf2");
set_optab_libfunc (le_optab, DFmode, "__mips16_ledf2");
floatsidf_libfunc = init_one_libfunc ("__mips16_floatsidf");
fixdfsi_libfunc = init_one_libfunc ("__mips16_fixdfsi");
set_conv_libfunc (sext_optab, DFmode, SFmode, "__mips16_extendsfdf2");
set_conv_libfunc (trunc_optab, SFmode, DFmode, "__mips16_truncdfsf2");
extendsfdf2_libfunc = init_one_libfunc ("__mips16_extendsfdf2");
truncdfsf2_libfunc = init_one_libfunc ("__mips16_truncdfsf2");
set_conv_libfunc (sfix_optab, SImode, DFmode, "__mips16_fixdfsi");
set_conv_libfunc (sfloat_optab, DFmode, SImode, "__mips16_floatsidf");
}
}
else

View File

@ -37,7 +37,6 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "expr.h"
#include "optabs.h"
#include "libfuncs.h"
#include "reload.h"
#include "integrate.h"
#include "function.h"
@ -4980,18 +4979,20 @@ pa_hpux_init_libfuncs (void)
set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
extendsftf2_libfunc = init_one_libfunc ("_U_Qfcnvff_sgl_to_quad");
extenddftf2_libfunc = init_one_libfunc ("_U_Qfcnvff_dbl_to_quad");
trunctfsf2_libfunc = init_one_libfunc ("_U_Qfcnvff_quad_to_sgl");
trunctfdf2_libfunc = init_one_libfunc ("_U_Qfcnvff_quad_to_dbl");
floatsitf_libfunc = init_one_libfunc ("_U_Qfcnvxf_sgl_to_quad");
floatditf_libfunc = init_one_libfunc ("_U_Qfcnvxf_dbl_to_quad");
fixtfsi_libfunc = init_one_libfunc (TARGET_64BIT
? "__U_Qfcnvfxt_quad_to_sgl"
: "_U_Qfcnvfxt_quad_to_sgl");
fixtfdi_libfunc = init_one_libfunc ("_U_Qfcnvfxt_quad_to_dbl");
fixunstfsi_libfunc = init_one_libfunc ("_U_Qfcnvfxt_quad_to_usgl");
fixunstfdi_libfunc = init_one_libfunc ("_U_Qfcnvfxt_quad_to_udbl");
set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
set_conv_libfunc (sfix_optab, SImode, TFmode, TARGET_64BIT
? "__U_Qfcnvfxt_quad_to_sgl"
: "_U_Qfcnvfxt_quad_to_sgl");
set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
set_conv_libfunc (ufix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_usgl");
set_conv_libfunc (ufix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_udbl");
set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
}
#endif

View File

@ -37,7 +37,6 @@
#include "tree.h"
#include "expr.h"
#include "optabs.h"
#include "libfuncs.h"
#include "except.h"
#include "function.h"
#include "output.h"
@ -6784,8 +6783,8 @@ rs6000_init_libfuncs (void)
if (TARGET_XCOFF && ! TARGET_POWER2 && ! TARGET_POWERPC)
{
/* AIX library routines for float->int conversion. */
fixdfsi_libfunc = init_one_libfunc ("__itrunc");
fixunsdfsi_libfunc = init_one_libfunc ("__uitrunc");
set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
}
/* Standard AIX/Darwin/64-bit SVR4 quad floating point routines. */
@ -6813,17 +6812,15 @@ rs6000_init_libfuncs (void)
set_optab_libfunc (lt_optab, TFmode, "_q_flt");
set_optab_libfunc (le_optab, TFmode, "_q_fle");
trunctfsf2_libfunc = init_one_libfunc ("_q_qtos");
trunctfdf2_libfunc = init_one_libfunc ("_q_qtod");
extendsftf2_libfunc = init_one_libfunc ("_q_stoq");
extenddftf2_libfunc = init_one_libfunc ("_q_dtoq");
floatsitf_libfunc = init_one_libfunc ("_q_itoq");
fixtfsi_libfunc = init_one_libfunc ("_q_qtoi");
fixunstfsi_libfunc = init_one_libfunc ("_q_qtou");
set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
}
}
/* Expand a block move operation, and return 1 if successful. Return 0
if we should let the compiler generate normal code.

View File

@ -39,7 +39,6 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "expr.h"
#include "optabs.h"
#include "libfuncs.h"
#include "recog.h"
#include "toplev.h"
#include "ggc.h"
@ -8431,20 +8430,21 @@ sparc_init_libfuncs (void)
set_optab_libfunc (lt_optab, TFmode, "_Q_flt");
set_optab_libfunc (le_optab, TFmode, "_Q_fle");
trunctfsf2_libfunc = init_one_libfunc ("_Q_qtos");
trunctfdf2_libfunc = init_one_libfunc ("_Q_qtod");
extendsftf2_libfunc = init_one_libfunc ("_Q_stoq");
extenddftf2_libfunc = init_one_libfunc ("_Q_dtoq");
floatsitf_libfunc = init_one_libfunc ("_Q_itoq");
fixtfsi_libfunc = init_one_libfunc ("_Q_qtoi");
fixunstfsi_libfunc = init_one_libfunc ("_Q_qtou");
set_conv_libfunc (sext_optab, TFmode, SFmode, "_Q_stoq");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_Q_dtoq");
set_conv_libfunc (trunc_optab, SFmode, TFmode, "_Q_qtos");
set_conv_libfunc (trunc_optab, DFmode, TFmode, "_Q_qtod");
set_conv_libfunc (sfix_optab, SImode, TFmode, "_Q_qtoi");
set_conv_libfunc (ufix_optab, SImode, TFmode, "_Q_qtou");
set_conv_libfunc (sfloat_optab, TFmode, SImode, "_Q_itoq");
if (SUN_CONVERSION_LIBFUNCS)
{
fixsfdi_libfunc = init_one_libfunc ("__ftoll");
fixunssfdi_libfunc = init_one_libfunc ("__ftoull");
fixdfdi_libfunc = init_one_libfunc ("__dtoll");
fixunsdfdi_libfunc = init_one_libfunc ("__dtoull");
set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoull");
set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoull");
}
}
if (TARGET_ARCH64)
@ -8470,10 +8470,10 @@ sparc_init_libfuncs (void)
if (SUN_CONVERSION_LIBFUNCS)
{
fixsfdi_libfunc = init_one_libfunc ("__ftol");
fixunssfdi_libfunc = init_one_libfunc ("__ftoul");
fixdfdi_libfunc = init_one_libfunc ("__dtol");
fixunsdfdi_libfunc = init_one_libfunc ("__dtoul");
set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftol");
set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoul");
set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtol");
set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoul");
}
}

View File

@ -595,248 +595,32 @@ convert_move (rtx to, rtx from, int unsignedp)
return;
}
if (to_real != from_real)
abort ();
if (to_real)
{
rtx value, insns;
convert_optab tab;
if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode))
{
/* Try converting directly if the insn is supported. */
if ((code = can_extend_p (to_mode, from_mode, 0))
!= CODE_FOR_nothing)
{
emit_unop_insn (code, to, from, UNKNOWN);
return;
}
}
tab = sext_optab;
else if (GET_MODE_BITSIZE (from_mode) > GET_MODE_BITSIZE (to_mode))
tab = trunc_optab;
else
abort ();
#ifdef HAVE_trunchfqf2
if (HAVE_trunchfqf2 && from_mode == HFmode && to_mode == QFmode)
/* Try converting directly if the insn is supported. */
code = tab->handlers[to_mode][from_mode].insn_code;
if (code != CODE_FOR_nothing)
{
emit_unop_insn (CODE_FOR_trunchfqf2, to, from, UNKNOWN);
emit_unop_insn (code, to, from,
tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
return;
}
#endif
#ifdef HAVE_trunctqfqf2
if (HAVE_trunctqfqf2 && from_mode == TQFmode && to_mode == QFmode)
{
emit_unop_insn (CODE_FOR_trunctqfqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncsfqf2
if (HAVE_truncsfqf2 && from_mode == SFmode && to_mode == QFmode)
{
emit_unop_insn (CODE_FOR_truncsfqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncdfqf2
if (HAVE_truncdfqf2 && from_mode == DFmode && to_mode == QFmode)
{
emit_unop_insn (CODE_FOR_truncdfqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncxfqf2
if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)
{
emit_unop_insn (CODE_FOR_truncxfqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_trunctfqf2
if (HAVE_trunctfqf2 && from_mode == TFmode && to_mode == QFmode)
{
emit_unop_insn (CODE_FOR_trunctfqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_trunctqfhf2
if (HAVE_trunctqfhf2 && from_mode == TQFmode && to_mode == HFmode)
{
emit_unop_insn (CODE_FOR_trunctqfhf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncsfhf2
if (HAVE_truncsfhf2 && from_mode == SFmode && to_mode == HFmode)
{
emit_unop_insn (CODE_FOR_truncsfhf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncdfhf2
if (HAVE_truncdfhf2 && from_mode == DFmode && to_mode == HFmode)
{
emit_unop_insn (CODE_FOR_truncdfhf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncxfhf2
if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)
{
emit_unop_insn (CODE_FOR_truncxfhf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_trunctfhf2
if (HAVE_trunctfhf2 && from_mode == TFmode && to_mode == HFmode)
{
emit_unop_insn (CODE_FOR_trunctfhf2, to, from, UNKNOWN);
return;
}
#endif
/* Otherwise use a libcall. */
libcall = tab->handlers[to_mode][from_mode].libfunc;
#ifdef HAVE_truncsftqf2
if (HAVE_truncsftqf2 && from_mode == SFmode && to_mode == TQFmode)
{
emit_unop_insn (CODE_FOR_truncsftqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncdftqf2
if (HAVE_truncdftqf2 && from_mode == DFmode && to_mode == TQFmode)
{
emit_unop_insn (CODE_FOR_truncdftqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncxftqf2
if (HAVE_truncxftqf2 && from_mode == XFmode && to_mode == TQFmode)
{
emit_unop_insn (CODE_FOR_truncxftqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_trunctftqf2
if (HAVE_trunctftqf2 && from_mode == TFmode && to_mode == TQFmode)
{
emit_unop_insn (CODE_FOR_trunctftqf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncdfsf2
if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)
{
emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncxfsf2
if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
{
emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_trunctfsf2
if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)
{
emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_truncxfdf2
if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
{
emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
return;
}
#endif
#ifdef HAVE_trunctfdf2
if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)
{
emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);
return;
}
#endif
libcall = (rtx) 0;
switch (from_mode)
{
case SFmode:
switch (to_mode)
{
case DFmode:
libcall = extendsfdf2_libfunc;
break;
case XFmode:
libcall = extendsfxf2_libfunc;
break;
case TFmode:
libcall = extendsftf2_libfunc;
break;
default:
break;
}
break;
case DFmode:
switch (to_mode)
{
case SFmode:
libcall = truncdfsf2_libfunc;
break;
case XFmode:
libcall = extenddfxf2_libfunc;
break;
case TFmode:
libcall = extenddftf2_libfunc;
break;
default:
break;
}
break;
case XFmode:
switch (to_mode)
{
case SFmode:
libcall = truncxfsf2_libfunc;
break;
case DFmode:
libcall = truncxfdf2_libfunc;
break;
default:
break;
}
break;
case TFmode:
switch (to_mode)
{
case SFmode:
libcall = trunctfsf2_libfunc;
break;
case DFmode:
libcall = trunctfdf2_libfunc;
break;
default:
break;
}
break;
default:
break;
}
if (libcall == (rtx) 0)
if (!libcall)
/* This conversion is not implemented yet. */
abort ();
@ -850,6 +634,42 @@ convert_move (rtx to, rtx from, int unsignedp)
return;
}
/* Handle pointer conversion. */ /* SPEE 900220. */
/* Targets are expected to provide conversion insns between PxImode and
xImode for all MODE_PARTIAL_INT modes they use, but no others. */
if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
{
enum machine_mode full_mode
= smallest_mode_for_size (GET_MODE_BITSIZE (to_mode), MODE_INT);
if (trunc_optab->handlers[to_mode][full_mode].insn_code
== CODE_FOR_nothing)
abort ();
if (full_mode != from_mode)
from = convert_to_mode (full_mode, from, unsignedp);
emit_unop_insn (trunc_optab->handlers[to_mode][full_mode].insn_code,
to, from, UNKNOWN);
return;
}
if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
{
enum machine_mode full_mode
= smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
if (sext_optab->handlers[full_mode][from_mode].insn_code
== CODE_FOR_nothing)
abort ();
emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
to, from, UNKNOWN);
if (to_mode == full_mode)
return;
/* else proceed to integer conversions below */
from_mode = full_mode;
}
/* Now both modes are integers. */
/* Handle expanding beyond a word. */
@ -972,119 +792,6 @@ convert_move (rtx to, rtx from, int unsignedp)
return;
}
/* Handle pointer conversion. */ /* SPEE 900220. */
if (to_mode == PQImode)
{
if (from_mode != QImode)
from = convert_to_mode (QImode, from, unsignedp);
#ifdef HAVE_truncqipqi2
if (HAVE_truncqipqi2)
{
emit_unop_insn (CODE_FOR_truncqipqi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_truncqipqi2 */
abort ();
}
if (from_mode == PQImode)
{
if (to_mode != QImode)
{
from = convert_to_mode (QImode, from, unsignedp);
from_mode = QImode;
}
else
{
#ifdef HAVE_extendpqiqi2
if (HAVE_extendpqiqi2)
{
emit_unop_insn (CODE_FOR_extendpqiqi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_extendpqiqi2 */
abort ();
}
}
if (to_mode == PSImode)
{
if (from_mode != SImode)
from = convert_to_mode (SImode, from, unsignedp);
#ifdef HAVE_truncsipsi2
if (HAVE_truncsipsi2)
{
emit_unop_insn (CODE_FOR_truncsipsi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_truncsipsi2 */
abort ();
}
if (from_mode == PSImode)
{
if (to_mode != SImode)
{
from = convert_to_mode (SImode, from, unsignedp);
from_mode = SImode;
}
else
{
#ifdef HAVE_extendpsisi2
if (! unsignedp && HAVE_extendpsisi2)
{
emit_unop_insn (CODE_FOR_extendpsisi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_extendpsisi2 */
#ifdef HAVE_zero_extendpsisi2
if (unsignedp && HAVE_zero_extendpsisi2)
{
emit_unop_insn (CODE_FOR_zero_extendpsisi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_zero_extendpsisi2 */
abort ();
}
}
if (to_mode == PDImode)
{
if (from_mode != DImode)
from = convert_to_mode (DImode, from, unsignedp);
#ifdef HAVE_truncdipdi2
if (HAVE_truncdipdi2)
{
emit_unop_insn (CODE_FOR_truncdipdi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_truncdipdi2 */
abort ();
}
if (from_mode == PDImode)
{
if (to_mode != DImode)
{
from = convert_to_mode (DImode, from, unsignedp);
from_mode = DImode;
}
else
{
#ifdef HAVE_extendpdidi2
if (HAVE_extendpdidi2)
{
emit_unop_insn (CODE_FOR_extendpdidi2, to, from, UNKNOWN);
return;
}
#endif /* HAVE_extendpdidi2 */
abort ();
}
}
/* Now follow all the conversions between integers
no more than a word long. */
@ -1158,140 +865,20 @@ convert_move (rtx to, rtx from, int unsignedp)
}
/* Support special truncate insns for certain modes. */
if (from_mode == DImode && to_mode == SImode)
if (trunc_optab->handlers[to_mode][from_mode].insn_code != CODE_FOR_nothing)
{
#ifdef HAVE_truncdisi2
if (HAVE_truncdisi2)
{
emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == DImode && to_mode == HImode)
{
#ifdef HAVE_truncdihi2
if (HAVE_truncdihi2)
{
emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == DImode && to_mode == QImode)
{
#ifdef HAVE_truncdiqi2
if (HAVE_truncdiqi2)
{
emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == SImode && to_mode == HImode)
{
#ifdef HAVE_truncsihi2
if (HAVE_truncsihi2)
{
emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == SImode && to_mode == QImode)
{
#ifdef HAVE_truncsiqi2
if (HAVE_truncsiqi2)
{
emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == HImode && to_mode == QImode)
{
#ifdef HAVE_trunchiqi2
if (HAVE_trunchiqi2)
{
emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == TImode && to_mode == DImode)
{
#ifdef HAVE_trunctidi2
if (HAVE_trunctidi2)
{
emit_unop_insn (CODE_FOR_trunctidi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == TImode && to_mode == SImode)
{
#ifdef HAVE_trunctisi2
if (HAVE_trunctisi2)
{
emit_unop_insn (CODE_FOR_trunctisi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == TImode && to_mode == HImode)
{
#ifdef HAVE_trunctihi2
if (HAVE_trunctihi2)
{
emit_unop_insn (CODE_FOR_trunctihi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
return;
}
if (from_mode == TImode && to_mode == QImode)
{
#ifdef HAVE_trunctiqi2
if (HAVE_trunctiqi2)
{
emit_unop_insn (CODE_FOR_trunctiqi2, to, from, UNKNOWN);
return;
}
#endif
convert_move (to, force_reg (from_mode, from), unsignedp);
emit_unop_insn (trunc_optab->handlers[to_mode][from_mode].insn_code,
to, from, UNKNOWN);
return;
}
/* Handle truncation of volatile memrefs, and so on;
the things that couldn't be truncated directly,
and for which there was no special instruction. */
and for which there was no special instruction.
??? Code above formerly short-circuited this, for most integer
mode pairs, with a force_reg in from_mode followed by a recursive
call to this routine. Appears always to have been wrong. */
if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
{
rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));

View File

@ -59,32 +59,33 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
upper-case forms of the comparison, respectively. */
static const char * const optabs[] =
{ "extendtab[$B][$A][0] = CODE_FOR_$(extend$a$b2$)",
"extendtab[$B][$A][1] = CODE_FOR_$(zero_extend$a$b2$)",
"fixtab[$A][$B][0] = CODE_FOR_$(fix$F$a$I$b2$)",
"fixtab[$A][$B][1] = CODE_FOR_$(fixuns$F$a$b2$)",
"fixtrunctab[$A][$B][0] = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
"fixtrunctab[$A][$B][1] = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
"floattab[$B][$A][0] = CODE_FOR_$(float$I$a$F$b2$)",
"floattab[$B][$A][1] = CODE_FOR_$(floatuns$I$a$F$b2$)",
{ "sext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(extend$a$b2$)",
"zext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(zero_extend$a$b2$)",
"sfix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix$F$a$I$b2$)",
"ufix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns$F$a$b2$)",
"sfixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
"ufixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
"sfloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(float$I$a$F$b2$)",
"ufloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(floatuns$I$a$F$b2$)",
"trunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(trunc$a$b2$)",
"add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
"addv_optab->handlers[(int) $A].insn_code =\n\
add_optab->handlers[(int) $A].insn_code = CODE_FOR_$(add$F$a3$)",
"addv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(addv$I$a3$)",
"addv_optab->handlers[$A].insn_code =\n\
add_optab->handlers[$A].insn_code = CODE_FOR_$(add$F$a3$)",
"addv_optab->handlers[$A].insn_code = CODE_FOR_$(addv$I$a3$)",
"sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
"subv_optab->handlers[(int) $A].insn_code =\n\
sub_optab->handlers[(int) $A].insn_code = CODE_FOR_$(sub$F$a3$)",
"subv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(subv$I$a3$)",
"subv_optab->handlers[$A].insn_code =\n\
sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$F$a3$)",
"subv_optab->handlers[$A].insn_code = CODE_FOR_$(subv$I$a3$)",
"smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
"smulv_optab->handlers[(int) $A].insn_code =\n\
smul_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mul$F$a3$)",
"smulv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mulv$I$a3$)",
"smulv_optab->handlers[$A].insn_code =\n\
smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$F$a3$)",
"smulv_optab->handlers[$A].insn_code = CODE_FOR_$(mulv$I$a3$)",
"umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
"smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
"smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
"umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
"sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
"sdivv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(div$V$I$a3$)",
"sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
"udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
"sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
"udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
@ -108,13 +109,13 @@ static const char * const optabs[] =
"pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
"atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
"neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
"negv_optab->handlers[(int) $A].insn_code =\n\
neg_optab->handlers[(int) $A].insn_code = CODE_FOR_$(neg$F$a2$)",
"negv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(negv$I$a2$)",
"negv_optab->handlers[$A].insn_code =\n\
neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$F$a2$)",
"negv_optab->handlers[$A].insn_code = CODE_FOR_$(negv$I$a2$)",
"abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
"absv_optab->handlers[(int) $A].insn_code =\n\
abs_optab->handlers[(int) $A].insn_code = CODE_FOR_$(abs$F$a2$)",
"absv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(absv$I$a2$)",
"absv_optab->handlers[$A].insn_code =\n\
abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
"absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
"sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
"floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
"ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
@ -229,7 +230,7 @@ gen_insn (rtx insn)
look through the modes in reverse order, in case
EXTRA_CC_MODES was used and CC is a prefix of the
CC modes (as it should be). */
for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
{
for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
if (TOLOWER (*p) != *q)
@ -303,16 +304,15 @@ gen_insn (rtx insn)
putchar (TOLOWER (*np));
break;
case 'A':
printf ("(int) %smode", GET_MODE_NAME(m1));
printf ("%smode", GET_MODE_NAME(m1));
break;
case 'B':
printf ("(int) %smode", GET_MODE_NAME(m2));
printf ("%smode", GET_MODE_NAME(m2));
break;
case 'c':
printf ("%s", GET_RTX_NAME(op));
break;
case 'C':
printf ("(int) ");
for (np = GET_RTX_NAME(op); *np; np++)
putchar (TOUPPER (*np));
break;
@ -368,7 +368,17 @@ from the machine description file `md'. */\n\n");
gen_insn (desc);
}
printf ("}\n");
puts ("\
\n\
#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
/* This flag says the same insns that convert to a signed fixnum\n\
also convert validly to an unsigned one. */\n\
for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
ufixtrunc_optab->handlers[i][j].insn_code\n\
= sfixtrunc_optab->handlers[i][j].insn_code;\n\
#endif\n\
}");
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);

View File

@ -24,18 +24,6 @@ Boston, MA 02111-1307, USA. */
/* Enumeration of indexes into libfunc_table. */
enum libfunc_index
{
LTI_extendsfdf2,
LTI_extendsfxf2,
LTI_extendsftf2,
LTI_extenddfxf2,
LTI_extenddftf2,
LTI_truncdfsf2,
LTI_truncxfsf2,
LTI_trunctfsf2,
LTI_truncxfdf2,
LTI_trunctfdf2,
LTI_abort,
LTI_memcpy,
LTI_memmove,
@ -53,54 +41,6 @@ enum libfunc_index
LTI_unwind_sjlj_register,
LTI_unwind_sjlj_unregister,
LTI_floatsisf,
LTI_floatdisf,
LTI_floattisf,
LTI_floatsidf,
LTI_floatdidf,
LTI_floattidf,
LTI_floatsixf,
LTI_floatdixf,
LTI_floattixf,
LTI_floatsitf,
LTI_floatditf,
LTI_floattitf,
LTI_fixsfsi,
LTI_fixsfdi,
LTI_fixsfti,
LTI_fixdfsi,
LTI_fixdfdi,
LTI_fixdfti,
LTI_fixxfsi,
LTI_fixxfdi,
LTI_fixxfti,
LTI_fixtfsi,
LTI_fixtfdi,
LTI_fixtfti,
LTI_fixunssfsi,
LTI_fixunssfdi,
LTI_fixunssfti,
LTI_fixunsdfsi,
LTI_fixunsdfdi,
LTI_fixunsdfti,
LTI_fixunsxfsi,
LTI_fixunsxfdi,
LTI_fixunsxfti,
LTI_fixunstfsi,
LTI_fixunstfdi,
LTI_fixunstfti,
LTI_profile_function_entry,
LTI_profile_function_exit,
@ -115,17 +55,6 @@ enum libfunc_index
extern GTY(()) rtx libfunc_table[LTI_MAX];
/* Accessor macros for libfunc_table. */
#define extendsfdf2_libfunc (libfunc_table[LTI_extendsfdf2])
#define extendsfxf2_libfunc (libfunc_table[LTI_extendsfxf2])
#define extendsftf2_libfunc (libfunc_table[LTI_extendsftf2])
#define extenddfxf2_libfunc (libfunc_table[LTI_extenddfxf2])
#define extenddftf2_libfunc (libfunc_table[LTI_extenddftf2])
#define truncdfsf2_libfunc (libfunc_table[LTI_truncdfsf2])
#define truncxfsf2_libfunc (libfunc_table[LTI_truncxfsf2])
#define trunctfsf2_libfunc (libfunc_table[LTI_trunctfsf2])
#define truncxfdf2_libfunc (libfunc_table[LTI_truncxfdf2])
#define trunctfdf2_libfunc (libfunc_table[LTI_trunctfdf2])
#define abort_libfunc (libfunc_table[LTI_abort])
#define memcpy_libfunc (libfunc_table[LTI_memcpy])
@ -145,54 +74,6 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
#define unwind_sjlj_unregister_libfunc \
(libfunc_table[LTI_unwind_sjlj_unregister])
#define floatsisf_libfunc (libfunc_table[LTI_floatsisf])
#define floatdisf_libfunc (libfunc_table[LTI_floatdisf])
#define floattisf_libfunc (libfunc_table[LTI_floattisf])
#define floatsidf_libfunc (libfunc_table[LTI_floatsidf])
#define floatdidf_libfunc (libfunc_table[LTI_floatdidf])
#define floattidf_libfunc (libfunc_table[LTI_floattidf])
#define floatsixf_libfunc (libfunc_table[LTI_floatsixf])
#define floatdixf_libfunc (libfunc_table[LTI_floatdixf])
#define floattixf_libfunc (libfunc_table[LTI_floattixf])
#define floatsitf_libfunc (libfunc_table[LTI_floatsitf])
#define floatditf_libfunc (libfunc_table[LTI_floatditf])
#define floattitf_libfunc (libfunc_table[LTI_floattitf])
#define fixsfsi_libfunc (libfunc_table[LTI_fixsfsi])
#define fixsfdi_libfunc (libfunc_table[LTI_fixsfdi])
#define fixsfti_libfunc (libfunc_table[LTI_fixsfti])
#define fixdfsi_libfunc (libfunc_table[LTI_fixdfsi])
#define fixdfdi_libfunc (libfunc_table[LTI_fixdfdi])
#define fixdfti_libfunc (libfunc_table[LTI_fixdfti])
#define fixxfsi_libfunc (libfunc_table[LTI_fixxfsi])
#define fixxfdi_libfunc (libfunc_table[LTI_fixxfdi])
#define fixxfti_libfunc (libfunc_table[LTI_fixxfti])
#define fixtfsi_libfunc (libfunc_table[LTI_fixtfsi])
#define fixtfdi_libfunc (libfunc_table[LTI_fixtfdi])
#define fixtfti_libfunc (libfunc_table[LTI_fixtfti])
#define fixunssfsi_libfunc (libfunc_table[LTI_fixunssfsi])
#define fixunssfdi_libfunc (libfunc_table[LTI_fixunssfdi])
#define fixunssfti_libfunc (libfunc_table[LTI_fixunssfti])
#define fixunsdfsi_libfunc (libfunc_table[LTI_fixunsdfsi])
#define fixunsdfdi_libfunc (libfunc_table[LTI_fixunsdfdi])
#define fixunsdfti_libfunc (libfunc_table[LTI_fixunsdfti])
#define fixunsxfsi_libfunc (libfunc_table[LTI_fixunsxfsi])
#define fixunsxfdi_libfunc (libfunc_table[LTI_fixunsxfdi])
#define fixunsxfti_libfunc (libfunc_table[LTI_fixunsxfti])
#define fixunstfsi_libfunc (libfunc_table[LTI_fixunstfsi])
#define fixunstfdi_libfunc (libfunc_table[LTI_fixunstfdi])
#define fixunstfti_libfunc (libfunc_table[LTI_fixunstfti])
#define profile_function_entry_libfunc (libfunc_table[LTI_profile_function_entry])
#define profile_function_exit_libfunc (libfunc_table[LTI_profile_function_exit])

View File

@ -58,13 +58,8 @@ optab optab_table[OTI_MAX];
rtx libfunc_table[LTI_MAX];
/* Tables of patterns for extending one integer mode to another. */
enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
/* Tables of patterns for converting between fixed and floating point. */
enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
/* Tables of patterns for converting one mode to another. */
convert_optab convert_optab_table[CTI_MAX];
/* Contains the optab used for each rtx code. */
optab code_to_optab[NUM_RTX_CODE + 1];
@ -112,11 +107,17 @@ static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
static rtx ftruncify (rtx);
static optab new_optab (void);
static convert_optab new_convert_optab (void);
static inline optab init_optab (enum rtx_code);
static inline optab init_optabv (enum rtx_code);
static inline convert_optab init_convert_optab (enum rtx_code);
static void init_libfuncs (optab, int, int, const char *, int);
static void init_integral_libfuncs (optab, const char *, int);
static void init_floating_libfuncs (optab, const char *, int);
static void init_interclass_conv_libfuncs (convert_optab, const char *,
enum mode_class, enum mode_class);
static void init_intraclass_conv_libfuncs (convert_optab, const char *,
enum mode_class, bool);
static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
enum rtx_code, int, rtx);
static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
@ -4421,12 +4422,14 @@ enum insn_code
can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
int unsignedp)
{
convert_optab tab;
#ifdef HAVE_ptr_extend
if (unsignedp < 0)
return CODE_FOR_ptr_extend;
else
#endif
return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
tab = unsignedp ? zext_optab : sext_optab;
return tab->handlers[to_mode][from_mode].insn_code;
}
/* Generate the body of an insn to extend Y (with mode MFROM)
@ -4436,7 +4439,8 @@ rtx
gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
enum machine_mode mfrom, int unsignedp)
{
return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
return GEN_FCN (icode) (x, y);
}
/* can_fix_p and can_float_p say whether the target machine
@ -4452,16 +4456,27 @@ static enum insn_code
can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
int unsignedp, int *truncp_ptr)
{
*truncp_ptr = 0;
if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
!= CODE_FOR_nothing)
return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
convert_optab tab;
enum insn_code icode;
if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
icode = tab->handlers[fixmode][fltmode].insn_code;
if (icode != CODE_FOR_nothing)
{
*truncp_ptr = 0;
return icode;
}
tab = unsignedp ? ufix_optab : sfix_optab;
icode = tab->handlers[fixmode][fltmode].insn_code;
if (icode != CODE_FOR_nothing
&& ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
{
*truncp_ptr = 1;
return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
return icode;
}
*truncp_ptr = 0;
return CODE_FOR_nothing;
}
@ -4469,7 +4484,10 @@ static enum insn_code
can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
int unsignedp)
{
return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
convert_optab tab;
tab = unsignedp ? ufloat_optab : sfloat_optab;
return tab->handlers[fltmode][fixmode].insn_code;
}
/* Generate code to convert FROM to floating point
@ -4642,12 +4660,12 @@ expand_float (rtx to, rtx from, int unsignedp)
goto done;
}
/* No hardware instruction available; call a library routine to convert from
SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
/* No hardware instruction available; call a library routine. */
{
rtx libfcn;
rtx libfunc;
rtx insns;
rtx value;
convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
to = protect_from_queue (to, 1);
from = protect_from_queue (from, 0);
@ -4658,56 +4676,13 @@ expand_float (rtx to, rtx from, int unsignedp)
if (flag_force_mem)
from = force_not_mem (from);
if (GET_MODE (to) == SFmode)
{
if (GET_MODE (from) == SImode)
libfcn = floatsisf_libfunc;
else if (GET_MODE (from) == DImode)
libfcn = floatdisf_libfunc;
else if (GET_MODE (from) == TImode)
libfcn = floattisf_libfunc;
else
abort ();
}
else if (GET_MODE (to) == DFmode)
{
if (GET_MODE (from) == SImode)
libfcn = floatsidf_libfunc;
else if (GET_MODE (from) == DImode)
libfcn = floatdidf_libfunc;
else if (GET_MODE (from) == TImode)
libfcn = floattidf_libfunc;
else
abort ();
}
else if (GET_MODE (to) == XFmode)
{
if (GET_MODE (from) == SImode)
libfcn = floatsixf_libfunc;
else if (GET_MODE (from) == DImode)
libfcn = floatdixf_libfunc;
else if (GET_MODE (from) == TImode)
libfcn = floattixf_libfunc;
else
abort ();
}
else if (GET_MODE (to) == TFmode)
{
if (GET_MODE (from) == SImode)
libfcn = floatsitf_libfunc;
else if (GET_MODE (from) == DImode)
libfcn = floatditf_libfunc;
else if (GET_MODE (from) == TImode)
libfcn = floattitf_libfunc;
else
abort ();
}
else
libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
if (!libfunc)
abort ();
start_sequence ();
value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
GET_MODE (to), 1, from,
GET_MODE (from));
insns = get_insns ();
@ -4748,7 +4723,6 @@ expand_fix (rtx to, rtx from, int unsignedp)
rtx target = to;
enum machine_mode fmode, imode;
int must_trunc = 0;
rtx libfcn = 0;
/* We first try to find a pair of modes, one real and one integer, at
least as wide as FROM and TO, respectively, in which we can open-code
@ -4889,57 +4863,16 @@ expand_fix (rtx to, rtx from, int unsignedp)
expand_fix (target, from, unsignedp);
}
else if (GET_MODE (from) == SFmode)
{
if (GET_MODE (to) == SImode)
libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
else if (GET_MODE (to) == DImode)
libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
else if (GET_MODE (to) == TImode)
libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
else
abort ();
}
else if (GET_MODE (from) == DFmode)
{
if (GET_MODE (to) == SImode)
libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
else if (GET_MODE (to) == DImode)
libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
else if (GET_MODE (to) == TImode)
libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
else
abort ();
}
else if (GET_MODE (from) == XFmode)
{
if (GET_MODE (to) == SImode)
libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
else if (GET_MODE (to) == DImode)
libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
else if (GET_MODE (to) == TImode)
libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
else
abort ();
}
else if (GET_MODE (from) == TFmode)
{
if (GET_MODE (to) == SImode)
libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
else if (GET_MODE (to) == DImode)
libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
else if (GET_MODE (to) == TImode)
libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
else
abort ();
}
else
abort ();
if (libfcn)
{
rtx insns;
rtx value;
rtx libfunc;
convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
if (!libfunc)
abort ();
to = protect_from_queue (to, 1);
from = protect_from_queue (from, 0);
@ -4949,7 +4882,7 @@ expand_fix (rtx to, rtx from, int unsignedp)
start_sequence ();
value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
GET_MODE (to), 1, from,
GET_MODE (from));
insns = get_insns ();
@ -4994,6 +4927,20 @@ new_optab (void)
return op;
}
static convert_optab
new_convert_optab (void)
{
int i, j;
convert_optab op = ggc_alloc (sizeof (struct convert_optab));
for (i = 0; i < NUM_MACHINE_MODES; i++)
for (j = 0; j < NUM_MACHINE_MODES; j++)
{
op->handlers[i][j].insn_code = CODE_FOR_nothing;
op->handlers[i][j].libfunc = 0;
}
return op;
}
/* Same, but fill in its code as CODE, and write it into the
code_to_optab table. */
static inline optab
@ -5015,6 +4962,15 @@ init_optabv (enum rtx_code code)
return op;
}
/* Conversion optabs never go in the code_to_optab table. */
static inline convert_optab
init_convert_optab (enum rtx_code code)
{
convert_optab op = new_convert_optab ();
op->code = code;
return op;
}
/* Initialize the libfunc fields of an entire group of entries in some
optab. Each entry is set equal to a string consisting of a leading
pair of underscores followed by a generic operation name followed by
@ -5101,6 +5057,119 @@ init_floating_libfuncs (optab optable, const char *opname, int suffix)
init_libfuncs (optable, lmode, lmode, opname, suffix);
}
/* Initialize the libfunc fields of an entire group of entries of an
inter-mode-class conversion optab. The string formation rules are
similar to the ones for init_libfuncs, above, but instead of having
a mode name and an operand count these functions have two mode names
and no operand count. */
static void
init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
enum mode_class from_class,
enum mode_class to_class)
{
enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
size_t opname_len = strlen (opname);
size_t max_mname_len = 0;
enum machine_mode fmode, tmode;
const char *fname, *tname;
const char *q;
char *libfunc_name, *suffix;
char *p;
for (fmode = first_from_mode;
fmode != VOIDmode;
fmode = GET_MODE_WIDER_MODE (fmode))
max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
for (tmode = first_to_mode;
tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
libfunc_name[0] = '_';
libfunc_name[1] = '_';
memcpy (&libfunc_name[2], opname, opname_len);
suffix = libfunc_name + opname_len + 2;
for (fmode = first_from_mode; fmode != VOIDmode;
fmode = GET_MODE_WIDER_MODE (fmode))
for (tmode = first_to_mode; tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
fname = GET_MODE_NAME (fmode);
tname = GET_MODE_NAME (tmode);
p = suffix;
for (q = fname; *q; p++, q++)
*p = TOLOWER (*q);
for (q = tname; *q; p++, q++)
*p = TOLOWER (*q);
*p = '\0';
tab->handlers[tmode][fmode].libfunc
= init_one_libfunc (ggc_alloc_string (libfunc_name,
p - libfunc_name));
}
}
/* Initialize the libfunc fields of an entire group of entries of an
intra-mode-class conversion optab. The string formation rules are
similar to the ones for init_libfunc, above. WIDENING says whether
the optab goes from narrow to wide modes or vice versa. These functions
have two mode names _and_ an operand count. */
static void
init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
enum mode_class class, bool widening)
{
enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
size_t opname_len = strlen (opname);
size_t max_mname_len = 0;
enum machine_mode nmode, wmode;
const char *nname, *wname;
const char *q;
char *libfunc_name, *suffix;
char *p;
for (nmode = first_mode; nmode != VOIDmode;
nmode = GET_MODE_WIDER_MODE (nmode))
max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
libfunc_name[0] = '_';
libfunc_name[1] = '_';
memcpy (&libfunc_name[2], opname, opname_len);
suffix = libfunc_name + opname_len + 2;
for (nmode = first_mode; nmode != VOIDmode;
nmode = GET_MODE_WIDER_MODE (nmode))
for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
wmode = GET_MODE_WIDER_MODE (wmode))
{
nname = GET_MODE_NAME (nmode);
wname = GET_MODE_NAME (wmode);
p = suffix;
for (q = widening ? nname : wname; *q; p++, q++)
*p = TOLOWER (*q);
for (q = widening ? wname : nname; *q; p++, q++)
*p = TOLOWER (*q);
*p++ = '2';
*p = '\0';
tab->handlers[widening ? nmode : wmode]
[widening ? wmode : nmode].libfunc
= init_one_libfunc (ggc_alloc_string (libfunc_name,
p - libfunc_name));
}
}
rtx
init_one_libfunc (const char *name)
{
@ -5136,36 +5205,29 @@ set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
optable->handlers[mode].libfunc = 0;
}
/* Call this to reset the function entry for one conversion optab
(OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
either 0 or a string constant. */
void
set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
enum machine_mode fmode, const char *name)
{
if (name)
optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
else
optable->handlers[tmode][fmode].libfunc = 0;
}
/* Call this once to initialize the contents of the optabs
appropriately for the current target machine. */
void
init_optabs (void)
{
unsigned int i, j, k;
unsigned int i;
/* Start by initializing all tables to contain CODE_FOR_nothing. */
for (i = 0; i < ARRAY_SIZE (fixtab); i++)
for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
fixtab[i][j][k] = CODE_FOR_nothing;
for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
fixtrunctab[i][j][k] = CODE_FOR_nothing;
for (i = 0; i < ARRAY_SIZE (floattab); i++)
for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
floattab[i][j][k] = CODE_FOR_nothing;
for (i = 0; i < ARRAY_SIZE (extendtab); i++)
for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
extendtab[i][j][k] = CODE_FOR_nothing;
for (i = 0; i < NUM_RTX_CODE; i++)
setcc_gen_code[i] = CODE_FOR_nothing;
@ -5239,7 +5301,7 @@ init_optabs (void)
floor_optab = init_optab (UNKNOWN);
ceil_optab = init_optab (UNKNOWN);
round_optab = init_optab (UNKNOWN);
trunc_optab = init_optab (UNKNOWN);
btrunc_optab = init_optab (UNKNOWN);
nearbyint_optab = init_optab (UNKNOWN);
sin_optab = init_optab (UNKNOWN);
cos_optab = init_optab (UNKNOWN);
@ -5253,6 +5315,17 @@ init_optabs (void)
cstore_optab = init_optab (UNKNOWN);
push_optab = init_optab (UNKNOWN);
/* Conversions. */
sext_optab = init_convert_optab (SIGN_EXTEND);
zext_optab = init_convert_optab (ZERO_EXTEND);
trunc_optab = init_convert_optab (TRUNCATE);
sfix_optab = init_convert_optab (FIX);
ufix_optab = init_convert_optab (UNSIGNED_FIX);
sfixtrunc_optab = init_convert_optab (UNKNOWN);
ufixtrunc_optab = init_convert_optab (UNKNOWN);
sfloat_optab = init_convert_optab (FLOAT);
ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
movstr_optab[i] = CODE_FOR_nothing;
@ -5266,14 +5339,6 @@ init_optabs (void)
/* Fill in the optabs with the insns we support. */
init_all_optabs ();
#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
/* This flag says the same insns that convert to a signed fixnum
also convert validly to an unsigned one. */
for (i = 0; i < NUM_MACHINE_MODES; i++)
for (j = 0; j < NUM_MACHINE_MODES; j++)
fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
#endif
/* Initialize the optabs with the names of the library functions. */
init_integral_libfuncs (add_optab, "add", '3');
init_floating_libfuncs (add_optab, "add", '3');
@ -5333,27 +5398,25 @@ init_optabs (void)
init_floating_libfuncs (le_optab, "le", '2');
init_floating_libfuncs (unord_optab, "unord", '2');
/* Use cabs for DC complex abs, since systems generally have cabs.
Don't define any libcall for SCmode, so that cabs will be used. */
abs_optab->handlers[(int) DCmode].libfunc
= init_one_libfunc ("cabs");
/* Conversions. */
init_interclass_conv_libfuncs (sfloat_optab, "float", MODE_INT, MODE_FLOAT);
init_interclass_conv_libfuncs (sfix_optab, "fix", MODE_FLOAT, MODE_INT);
init_interclass_conv_libfuncs (ufix_optab, "fixuns", MODE_FLOAT, MODE_INT);
/* The ffs function operates on `int'. */
/* sext_optab is also used for FLOAT_EXTEND. */
init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
/* Use cabs for double complex abs, since systems generally have cabs.
Don't define any libcall for float complex, so that cabs will be used. */
if (complex_double_type_node)
abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
= init_one_libfunc ("cabs");
/* The ffs function op[1erates on `int'. */
ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
= init_one_libfunc ("ffs");
extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
abort_libfunc = init_one_libfunc ("abort");
memcpy_libfunc = init_one_libfunc ("memcpy");
memmove_libfunc = init_one_libfunc ("memmove");
@ -5378,54 +5441,6 @@ init_optabs (void)
unwind_sjlj_unregister_libfunc
= init_one_libfunc ("_Unwind_SjLj_Unregister");
floatsisf_libfunc = init_one_libfunc ("__floatsisf");
floatdisf_libfunc = init_one_libfunc ("__floatdisf");
floattisf_libfunc = init_one_libfunc ("__floattisf");
floatsidf_libfunc = init_one_libfunc ("__floatsidf");
floatdidf_libfunc = init_one_libfunc ("__floatdidf");
floattidf_libfunc = init_one_libfunc ("__floattidf");
floatsixf_libfunc = init_one_libfunc ("__floatsixf");
floatdixf_libfunc = init_one_libfunc ("__floatdixf");
floattixf_libfunc = init_one_libfunc ("__floattixf");
floatsitf_libfunc = init_one_libfunc ("__floatsitf");
floatditf_libfunc = init_one_libfunc ("__floatditf");
floattitf_libfunc = init_one_libfunc ("__floattitf");
fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
fixsfti_libfunc = init_one_libfunc ("__fixsfti");
fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
fixdfti_libfunc = init_one_libfunc ("__fixdfti");
fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
fixxfti_libfunc = init_one_libfunc ("__fixxfti");
fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
fixtfti_libfunc = init_one_libfunc ("__fixtfti");
fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
/* For function entry/exit instrumentation. */
profile_function_entry_libfunc
= init_one_libfunc ("__cyg_profile_func_enter");

View File

@ -38,19 +38,32 @@ Boston, MA 02111-1307, USA. */
A few optabs, such as move_optab and cmp_optab, are used
by special code. */
struct optab_handlers GTY(())
{
enum insn_code insn_code;
rtx libfunc;
};
struct optab GTY(())
{
enum rtx_code code;
struct optab_handlers {
enum insn_code insn_code;
rtx libfunc;
} handlers [NUM_MACHINE_MODES];
struct optab_handlers handlers[NUM_MACHINE_MODES];
};
typedef struct optab * optab;
/* A convert_optab is for some sort of conversion operation between
modes. The first array index is the destination mode, the second
is the source mode. */
struct convert_optab GTY(())
{
enum rtx_code code;
struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
};
typedef struct convert_optab *convert_optab;
/* Given an enum insn_code, access the function to construct
the body of that kind of insn. */
#define GEN_FCN(CODE) (*insn_data[(int) (CODE)].genfun)
#define GEN_FCN(CODE) (insn_data[CODE].genfun)
/* Enumeration of valid indexes into optab_table. */
enum optab_index
@ -242,7 +255,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define log_optab (optab_table[OTI_log])
#define floor_optab (optab_table[OTI_floor])
#define ceil_optab (optab_table[OTI_ceil])
#define trunc_optab (optab_table[OTI_trunc])
#define btrunc_optab (optab_table[OTI_trunc])
#define round_optab (optab_table[OTI_round])
#define nearbyint_optab (optab_table[OTI_nearbyint])
#define tan_optab (optab_table[OTI_tan])
@ -268,13 +281,36 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define push_optab (optab_table[OTI_push])
#define addcc_optab (optab_table[OTI_addcc])
/* Tables of patterns for extending one integer mode to another. */
extern enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
/* Conversion optabs have their own table and indexes. */
enum convert_optab_index
{
CTI_sext,
CTI_zext,
CTI_trunc,
/* Tables of patterns for converting between fixed and floating point. */
extern enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
extern enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
extern enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
CTI_sfix,
CTI_ufix,
CTI_sfixtrunc,
CTI_ufixtrunc,
CTI_sfloat,
CTI_ufloat,
CTI_MAX
};
extern GTY(()) convert_optab convert_optab_table[CTI_MAX];
#define sext_optab (convert_optab_table[CTI_sext])
#define zext_optab (convert_optab_table[CTI_zext])
#define trunc_optab (convert_optab_table[CTI_trunc])
#define sfix_optab (convert_optab_table[CTI_sfix])
#define ufix_optab (convert_optab_table[CTI_ufix])
#define sfixtrunc_optab (convert_optab_table[CTI_sfixtrunc])
#define ufixtrunc_optab (convert_optab_table[CTI_ufixtrunc])
#define sfloat_optab (convert_optab_table[CTI_sfloat])
#define ufloat_optab (convert_optab_table[CTI_ufloat])
/* These arrays record the insn_code of insns that may be needed to
perform input and output reloads of special objects. They provide a
@ -385,6 +421,8 @@ extern void init_floattab (void);
/* Call this to reset the function entry for one optab. */
extern void set_optab_libfunc (optab, enum machine_mode, const char *);
extern void set_conv_libfunc (convert_optab, enum machine_mode,
enum machine_mode, const char *);
/* Generate code for a FLOAT_EXPR. */
extern void expand_float (rtx, rtx, int);