Commit a38e0142 by Sandra Loosemore Committed by Sandra Loosemore

Fix up MIPS16 hard float and add support for complex.

2007-05-23  Sandra Loosemore  <sandra@codesourcery.com>
	    Nigel Stephens  <nigel@mips.com>
	    Richard Sandiford  <richard@codesourcery.com>

	gcc/
	Fix up MIPS16 hard float and add support for complex.

	* config/mips/mips.h (TARGET_HARD_FLOAT_ABI): New.
	(TARGET_SOFT_FLOAT_ABI): New.
	(TARGET_CPU_CPP_BUILTINS): Define __mips_hard_float and
	__mips_soft_float to reflect the ABI in use, not whether the
	FPU is directly accessible (e.g., in MIPS16 mode).
	(UNITS_PER_HWFPVALUE): Use TARGET_SOFT_FLOAT_ABI.
	(UNITS_PER_FPVALUE): Likewise.

	* config/mips/mips.c (mips_expand_call): Remove redundant
	TARGET_MIPS16 check.
	(mips_arg_regno): New.
	(function_arg_advance): When setting bits in cum->fp_code for
	MIPS16, don't subtract 1 from cum->arg_number, since it is now
	zero-based.
	(function_arg): Use mips_arg_regno.
	(mips_return_mode_in_fpr_p): New.
	(mips16_call_stub_mode_suffix): New.
	(mips16_cfun_returns_in_fpr_p): New.
	(mips_save_reg_p): Use mips16_cfun_returns_in_fpr_p.
	(mips_output_function_prologue): Test mips16_hard_float, not
	!TARGET_SOFT_FLOAT, to decide when a function stub is required.
	(mips_expand_epilogue): Call MIPS16 helper routines to copy
	return value into a floating-point register.
	(mips_can_use_return_insn): Use mips16_cfun_returns_in_fpr_p.
	(mips_function_value): Rewrite to use mips_return_mode_in_fpr_p.
	(mips16_fp_args): Handle MIPS32r2 ISA which supports
	TARGET_FLOAT64, and use mfhc1/mthc1 to copy the most significant
	word of double arguments from or to the high bits of 64-bit
	floating point registers.
	(build_mips16_function_stub): Fill in DECL_RESULT for stubdecl.
	(mips16_fpret_double): New helper function.
	(build_mips16_call_stub): Use mips16_return_mode_in_fpr_p.  Add
	support for complex modes.  Fill in DECL_RESULT for stubdecl.
	(mips_init_libfuncs): Remove redundant TARGET_MIPS16 check.

	* config/mips/mips16.S 
	(RET, ARG1, ARG2): New.
	(MERGE_GPRf, MERGE_GPRt): New.
	(DELAYt, DELAYf): New.
	(MOVE_SF_BYTE0, MOVE_SI_BYTE0): New.
	(MOVE_SF_BYTE4, MOVE_SF_BYTE8): New.
	(MOVE_DF_BYTE0, MOVE_DF_BYTE8): New.
	(MOVE_SF_RET, MOVE_SC_RET, MOVE_DF_RET, MOVE_DC_RET, MOVE_SI_RET): New.
	(SFOP): Renamed to...
	(OPSF3): This, and macro-ified.  Updated all uses.
	(SFOP2): Renamed to...
	(OPSF2): This, and macro-ified.  Updated all uses.
	(SFCMP): Renamed to...
	(CMPSF): This, and macro-ified.  Updated all uses.
	(SFREVCMP): Renamed to...
	(REVCMPSF): This, and macro-ified.  Updated all uses.
	(__mips16_floatsisf, __mips16_fix_truncsfsi): Macro-ified.
	(LDDBL1, LDDBL2, RETDBL): Deleted.
	(DFOP): Renamed to...
	(OPDF3): This, and macro-ified.  Updated all uses.
	(DFOP2): Renamed to...
	(OPDF2): This, and macro-ified.  Updated all uses.
	(__mips16_extendsfdf2, __mips16_truncdfsf2): Macro-ified.
	(DFCMP): Renamed to...
	(CMPDF): This, and macro-ified.  Updated all uses.
	(DFREVCMP): Renamed to...
	(REVCMPDF): This, and macro-ified.  Updated all uses.
	(__mips16_floatsidf, __mips16_fix_truncdfsi): Macro-ified.
	(RET_FUNCTION): New.
	(__mips16_ret_sf, __mips16_ret_df): Macro-ified.
	(__mips16_ret_sc, __mips16_ret_dc): New.
	(STUB_ARGS_0, STUB_ARGS_1, STUB_ARGS_5, STUB_ARGS_9, STUB_ARGS_2,
	STUB_ARGS_6, STUB_ARGS_10): New.
	(CALL_STUB_NO_RET): New.
	(__mips16_call_stub_1): Macro-ified.
	(__mips16_call_stub_5): Macro-ified.
	(__mips16_call_stub_2): Macro-ified.
	(__mips16_call_stub_6): Macro-ified.
	(__mips16_call_stub_9): Macro-ified.
	(__mips16_call_stub_10): Macro-ified.
	(CALL_STUB_RET): New.
	(__mips16_call_stub_sf_0): Macro-ified.
	(__mips16_call_stub_sf_1): Macro-ified.
	(__mips16_call_stub_sf_5): Macro-ified.
	(__mips16_call_stub_sf_2): Macro-ified.
	(__mips16_call_stub_sf_6): Macro-ified.
	(__mips16_call_stub_sf_9): Macro-ified.
	(__mips16_call_stub_sf_10): Macro-ified.
	(__mips16_call_stub_df_0): Macro-ified.
	(__mips16_call_stub_df_1): Macro-ified.
	(__mips16_call_stub_df_5): Macro-ified.
	(__mips16_call_stub_df_2): Macro-ified.
	(__mips16_call_stub_df_6): Macro-ified.
	(__mips16_call_stub_df_9): Macro-ified.
	(__mips16_call_stub_df_10): Macro-ified.
	(__mips16_call_stub_sc_0): New.
	(__mips16_call_stub_sc_1): New.
	(__mips16_call_stub_sc_5): New.
	(__mips16_call_stub_sc_2): New.
	(__mips16_call_stub_sc_6): New.
	(__mips16_call_stub_sc_9): New.
	(__mips16_call_stub_sc_10): New.
	(__mips16_call_stub_dc_0): New.
	(__mips16_call_stub_dc_1): New.
	(__mips16_call_stub_dc_5): New.
	(__mips16_call_stub_dc_2): New.
	(__mips16_call_stub_dc_6): New.
	(__mips16_call_stub_dc_9): New.
	(__mips16_call_stub_dc_10): New.
	
	* config/mips/t-elf (LIB1ASMFUNCS): Add MIPS16 floating-point stubs.
	* config/mips/t-isa3264 (LIB1ASMFUNCS): Likewise.
	* config/mips/t-r2900 (LIB1ASMFUNCS): Likewise.

	gcc/testsuite/
	* gcc.target/mips/inter/mips16_stubs_1_main.c: New.
	* gcc.target/mips/inter/mips16_stubs_1_x.c: New.
	* gcc.target/mips/inter/mips16_stubs_1_y.c: New.
	* gcc.target/mips/inter/mips16-inter.exp: New.


Co-Authored-By: Nigel Stephens <nigel@mips.com>
Co-Authored-By: Richard Sandiford <richard@codesourcery.com>

From-SVN: r124999
parent 70c1e033
2007-05-23 Sandra Loosemore <sandra@codesourcery.com>
Nigel Stephens <nigel@mips.com>
Richard Sandiford <richard@codesourcery.com>
Fix up MIPS16 hard float and add support for complex.
* config/mips/mips.h (TARGET_HARD_FLOAT_ABI): New.
(TARGET_SOFT_FLOAT_ABI): New.
(TARGET_CPU_CPP_BUILTINS): Define __mips_hard_float and
__mips_soft_float to reflect the ABI in use, not whether the
FPU is directly accessible (e.g., in MIPS16 mode).
(UNITS_PER_HWFPVALUE): Use TARGET_SOFT_FLOAT_ABI.
(UNITS_PER_FPVALUE): Likewise.
* config/mips/mips.c (mips_expand_call): Remove redundant
TARGET_MIPS16 check.
(mips_arg_regno): New.
(function_arg_advance): When setting bits in cum->fp_code for
MIPS16, don't subtract 1 from cum->arg_number, since it is now
zero-based.
(function_arg): Use mips_arg_regno.
(mips_return_mode_in_fpr_p): New.
(mips16_call_stub_mode_suffix): New.
(mips16_cfun_returns_in_fpr_p): New.
(mips_save_reg_p): Use mips16_cfun_returns_in_fpr_p.
(mips_output_function_prologue): Test mips16_hard_float, not
!TARGET_SOFT_FLOAT, to decide when a function stub is required.
(mips_expand_epilogue): Call MIPS16 helper routines to copy
return value into a floating-point register.
(mips_can_use_return_insn): Use mips16_cfun_returns_in_fpr_p.
(mips_function_value): Rewrite to use mips_return_mode_in_fpr_p.
(mips16_fp_args): Handle MIPS32r2 ISA which supports
TARGET_FLOAT64, and use mfhc1/mthc1 to copy the most significant
word of double arguments from or to the high bits of 64-bit
floating point registers.
(build_mips16_function_stub): Fill in DECL_RESULT for stubdecl.
(mips16_fpret_double): New helper function.
(build_mips16_call_stub): Use mips16_return_mode_in_fpr_p. Add
support for complex modes. Fill in DECL_RESULT for stubdecl.
(mips_init_libfuncs): Remove redundant TARGET_MIPS16 check.
* config/mips/mips16.S
(RET, ARG1, ARG2): New.
(MERGE_GPRf, MERGE_GPRt): New.
(DELAYt, DELAYf): New.
(MOVE_SF_BYTE0, MOVE_SI_BYTE0): New.
(MOVE_SF_BYTE4, MOVE_SF_BYTE8): New.
(MOVE_DF_BYTE0, MOVE_DF_BYTE8): New.
(MOVE_SF_RET, MOVE_SC_RET, MOVE_DF_RET, MOVE_DC_RET, MOVE_SI_RET): New.
(SFOP): Renamed to...
(OPSF3): This, and macro-ified. Updated all uses.
(SFOP2): Renamed to...
(OPSF2): This, and macro-ified. Updated all uses.
(SFCMP): Renamed to...
(CMPSF): This, and macro-ified. Updated all uses.
(SFREVCMP): Renamed to...
(REVCMPSF): This, and macro-ified. Updated all uses.
(__mips16_floatsisf, __mips16_fix_truncsfsi): Macro-ified.
(LDDBL1, LDDBL2, RETDBL): Deleted.
(DFOP): Renamed to...
(OPDF3): This, and macro-ified. Updated all uses.
(DFOP2): Renamed to...
(OPDF2): This, and macro-ified. Updated all uses.
(__mips16_extendsfdf2, __mips16_truncdfsf2): Macro-ified.
(DFCMP): Renamed to...
(CMPDF): This, and macro-ified. Updated all uses.
(DFREVCMP): Renamed to...
(REVCMPDF): This, and macro-ified. Updated all uses.
(__mips16_floatsidf, __mips16_fix_truncdfsi): Macro-ified.
(RET_FUNCTION): New.
(__mips16_ret_sf, __mips16_ret_df): Macro-ified.
(__mips16_ret_sc, __mips16_ret_dc): New.
(STUB_ARGS_0, STUB_ARGS_1, STUB_ARGS_5, STUB_ARGS_9, STUB_ARGS_2,
STUB_ARGS_6, STUB_ARGS_10): New.
(CALL_STUB_NO_RET): New.
(__mips16_call_stub_1): Macro-ified.
(__mips16_call_stub_5): Macro-ified.
(__mips16_call_stub_2): Macro-ified.
(__mips16_call_stub_6): Macro-ified.
(__mips16_call_stub_9): Macro-ified.
(__mips16_call_stub_10): Macro-ified.
(CALL_STUB_RET): New.
(__mips16_call_stub_sf_0): Macro-ified.
(__mips16_call_stub_sf_1): Macro-ified.
(__mips16_call_stub_sf_5): Macro-ified.
(__mips16_call_stub_sf_2): Macro-ified.
(__mips16_call_stub_sf_6): Macro-ified.
(__mips16_call_stub_sf_9): Macro-ified.
(__mips16_call_stub_sf_10): Macro-ified.
(__mips16_call_stub_df_0): Macro-ified.
(__mips16_call_stub_df_1): Macro-ified.
(__mips16_call_stub_df_5): Macro-ified.
(__mips16_call_stub_df_2): Macro-ified.
(__mips16_call_stub_df_6): Macro-ified.
(__mips16_call_stub_df_9): Macro-ified.
(__mips16_call_stub_df_10): Macro-ified.
(__mips16_call_stub_sc_0): New.
(__mips16_call_stub_sc_1): New.
(__mips16_call_stub_sc_5): New.
(__mips16_call_stub_sc_2): New.
(__mips16_call_stub_sc_6): New.
(__mips16_call_stub_sc_9): New.
(__mips16_call_stub_sc_10): New.
(__mips16_call_stub_dc_0): New.
(__mips16_call_stub_dc_1): New.
(__mips16_call_stub_dc_5): New.
(__mips16_call_stub_dc_2): New.
(__mips16_call_stub_dc_6): New.
(__mips16_call_stub_dc_9): New.
(__mips16_call_stub_dc_10): New.
* config/mips/t-elf (LIB1ASMFUNCS): Add MIPS16 floating-point stubs.
* config/mips/t-isa3264 (LIB1ASMFUNCS): Likewise.
* config/mips/t-r2900 (LIB1ASMFUNCS): Likewise.
2007-05-23 Ian Lance Taylor <iant@google.com>
* doc/invoke.texi (Invoking GCC): Document that the order of the
......
......@@ -288,6 +288,11 @@ extern const struct mips_rtx_cost_data *mips_cost;
#define TARGET_OLDABI (mips_abi == ABI_32 || mips_abi == ABI_O64)
#define TARGET_NEWABI (mips_abi == ABI_N32 || mips_abi == ABI_64)
/* Similar to TARGET_HARD_FLOAT and TARGET_SOFT_FLOAT, but reflect the ABI
in use rather than whether the FPU is directly accessible. */
#define TARGET_HARD_FLOAT_ABI (TARGET_HARD_FLOAT || mips16_hard_float)
#define TARGET_SOFT_FLOAT_ABI (!TARGET_HARD_FLOAT_ABI)
/* IRIX specific stuff. */
#define TARGET_IRIX 0
#define TARGET_IRIX6 0
......@@ -406,9 +411,11 @@ extern const struct mips_rtx_cost_data *mips_cost;
builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \
} \
\
if (TARGET_HARD_FLOAT) \
/* These defines reflect the ABI in use, not whether the \
FPU is directly accessible. */ \
if (TARGET_HARD_FLOAT_ABI) \
builtin_define ("__mips_hard_float"); \
else if (TARGET_SOFT_FLOAT) \
else \
builtin_define ("__mips_soft_float"); \
\
if (TARGET_SINGLE_FLOAT) \
......@@ -1033,12 +1040,12 @@ extern const struct mips_rtx_cost_data *mips_cost;
/* The largest size of value that can be held in floating-point
registers and moved with a single instruction. */
#define UNITS_PER_HWFPVALUE \
(TARGET_SOFT_FLOAT ? 0 : MAX_FPRS_PER_FMT * UNITS_PER_FPREG)
(TARGET_SOFT_FLOAT_ABI ? 0 : MAX_FPRS_PER_FMT * UNITS_PER_FPREG)
/* The largest size of value that can be held in floating-point
registers. */
#define UNITS_PER_FPVALUE \
(TARGET_SOFT_FLOAT ? 0 \
(TARGET_SOFT_FLOAT_ABI ? 0 \
: TARGET_SINGLE_FLOAT ? UNITS_PER_FPREG \
: LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)
......
......@@ -19,11 +19,16 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
_m16eqdf2 _m16nedf2 _m16gtdf2 _m16gedf2 _m16ledf2 _m16ltdf2 \
_m16fltsidf _m16fix_truncdfsi \
_m16retsf _m16retdf \
_m16retsc _m16retdc \
_m16stub1 _m16stub2 _m16stub5 _m16stub6 _m16stub9 _m16stub10 \
_m16stubsf0 _m16stubsf1 _m16stubsf2 _m16stubsf5 _m16stubsf6 \
_m16stubsf9 _m16stubsf10 \
_m16stubdf0 _m16stubdf1 _m16stubdf2 _m16stubdf5 _m16stubdf6 \
_m16stubdf9 _m16stubdf10
_m16stubdf9 _m16stubdf10 \
_m16stubsc0 _m16stubsc1 _m16stubsc2 _m16stubsc5 _m16stubsc6 \
_m16stubsc9 _m16stubsc10 \
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
_m16stubdc9 _m16stubdc10
# We must build libgcc2.a with -G 0, in case the user wants to link
# without the $gp register.
......
......@@ -19,11 +19,16 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
_m16eqdf2 _m16nedf2 _m16gtdf2 _m16gedf2 _m16ledf2 _m16ltdf2 \
_m16fltsidf _m16fix_truncdfsi \
_m16retsf _m16retdf \
_m16retsc _m16retdc \
_m16stub1 _m16stub2 _m16stub5 _m16stub6 _m16stub9 _m16stub10 \
_m16stubsf0 _m16stubsf1 _m16stubsf2 _m16stubsf5 _m16stubsf6 \
_m16stubsf9 _m16stubsf10 \
_m16stubdf0 _m16stubdf1 _m16stubdf2 _m16stubdf5 _m16stubdf6 \
_m16stubdf9 _m16stubdf10
_m16stubdf9 _m16stubdf10 \
_m16stubsc0 _m16stubsc1 _m16stubsc2 _m16stubsc5 _m16stubsc6 \
_m16stubsc9 _m16stubsc10 \
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
_m16stubdc9 _m16stubdc10
# We must build libgcc2.a with -G 0, in case the user wants to link
# without the $gp register.
......
......@@ -7,11 +7,16 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
_m16eqdf2 _m16nedf2 _m16gtdf2 _m16gedf2 _m16ledf2 _m16ltdf2 \
_m16fltsidf _m16fix_truncdfsi \
_m16retsf _m16retdf \
_m16retsc _m16retdc \
_m16stub1 _m16stub2 _m16stub5 _m16stub6 _m16stub9 _m16stub10 \
_m16stubsf0 _m16stubsf1 _m16stubsf2 _m16stubsf5 _m16stubsf6 \
_m16stubsf9 _m16stubsf10 \
_m16stubdf0 _m16stubdf1 _m16stubdf2 _m16stubdf5 _m16stubdf6 \
_m16stubdf9 _m16stubdf10
_m16stubdf9 _m16stubdf10 \
_m16stubsc0 _m16stubsc1 _m16stubsc2 _m16stubsc5 _m16stubsc6 \
_m16stubsc9 _m16stubsc10 \
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
_m16stubdc9 _m16stubdc10
# We must build libgcc2.a with -G 0, in case the user wants to link
# without the $gp register.
......
2007-05-23 Sandra Loosemore <sandra@codesourcery.com>
Nigel Stephens <nigel@mips.com>
Richard Sandiford <richard@codesourcery.com>
* gcc.target/mips/inter/mips16_stubs_1_main.c: New.
* gcc.target/mips/inter/mips16_stubs_1_x.c: New.
* gcc.target/mips/inter/mips16_stubs_1_y.c: New.
* gcc.target/mips/inter/mips16-inter.exp: New.
2007-05-23 Kazu Hirata <kazu@codesourcery.com>
* gcc.dg/bf-spl1.c, gcc.dg/m68k-pic-1.c: Enable on fido-*-*.
# Run compatibility tests in which the "alt" compiler tries to force
# MIPS16 mode.
# We can only guarantee MIPS16 runtime support for certain targets.
if { ![istarget mipsisa*-*-elf*] && ![istarget mips64vr*-*-elf*] } {
return
}
# Save the old value of CFLAGS_FOR_TARGET, if any.
global saved_CFLAGS_FOR_TARGET
if { [info exists CFLAGS_FOR_TARGET] } {
set saved_CFLAGS_FOR_TARGET $CFLAGS_FOR_TARGET
} else {
unset -nocomplain saved_CFLAGS_FOR_TARGET
}
# The "alt" compiler is the normal compiler with an extra "-mips16" argument.
proc compat-use-alt-compiler { } {
global saved_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET
if { [info exists saved_CFLAGS_FOR_TARGET] } {
set CFLAGS_FOR_TARGET [concat $saved_CFLAGS_FOR_TARGET "-mips16"]
} else {
set CFLAGS_FOR_TARGET "-mips16"
}
}
# Make the compiler under test the default.
proc compat-use-tst-compiler { } {
global saved_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET
if { [info exists saved_CFLAGS_FOR_TARGET] } {
set CFLAGS_FOR_TARGET $saved_CFLAGS_FOR_TARGET
} else {
unset -nocomplain CFLAGS_FOR_TARGET
}
}
load_lib gcc.exp
load_lib compat.exp
gcc_init
foreach src [lsort [find $srcdir/$subdir mips16_*_main.c]] {
if { [runtest_file_p $runtests $src] } {
compat-execute $src "mips16_inter" 1
}
}
compat-use-tst-compiler
extern void init (void);
extern void test (void);
int
main (void)
{
init ();
test ();
return 0;
}
#include <stdlib.h>
/* All the function pointers are declared and initialized in
mips16-stubs-2.c. */
extern double the_result;
extern void v0 (void);
extern void v1 (float);
extern void v5 (float, float);
extern void v9 (float, double);
extern void v2 (double);
extern void v6 (double, float);
extern void v10 (double, double);
extern float f0 (void);
extern float f1 (float);
extern float f5 (float, float);
extern float f9 (float, double);
extern float f2 (double);
extern float f6 (double, float);
extern float f10 (double, double);
extern double d0 (void);
extern double d1 (float);
extern double d5 (float, float);
extern double d9 (float, double);
extern double d2 (double);
extern double d6 (double, float);
extern double d10 (double, double);
extern _Complex float cf0 (void);
extern _Complex float cf1 (float);
extern _Complex float cf5 (float, float);
extern _Complex float cf9 (float, double);
extern _Complex float cf2 (double);
extern _Complex float cf6 (double, float);
extern _Complex float cf10 (double, double);
extern _Complex double cd0 (void);
extern _Complex double cd1 (float);
extern _Complex double cd5 (float, float);
extern _Complex double cd9 (float, double);
extern _Complex double cd2 (double);
extern _Complex double cd6 (double, float);
extern _Complex double cd10 (double, double);
extern void (*pv0) (void);
extern void (*pv1) (float);
extern void (*pv5) (float, float);
extern void (*pv9) (float, double);
extern void (*pv2) (double);
extern void (*pv6) (double, float);
extern void (*pv10) (double, double);
extern float (*pf0) (void);
extern float (*pf1) (float);
extern float (*pf5) (float, float);
extern float (*pf9) (float, double);
extern float (*pf2) (double);
extern float (*pf6) (double, float);
extern float (*pf10) (double, double);
extern double (*pd0) (void);
extern double (*pd1) (float);
extern double (*pd5) (float, float);
extern double (*pd9) (float, double);
extern double (*pd2) (double);
extern double (*pd6) (double, float);
extern double (*pd10) (double, double);
extern _Complex float (*pcf0) (void);
extern _Complex float (*pcf1) (float);
extern _Complex float (*pcf5) (float, float);
extern _Complex float (*pcf9) (float, double);
extern _Complex float (*pcf2) (double);
extern _Complex float (*pcf6) (double, float);
extern _Complex float (*pcf10) (double, double);
extern _Complex double (*pcd0) (void);
extern _Complex double (*pcd1) (float);
extern _Complex double (*pcd5) (float, float);
extern _Complex double (*pcd9) (float, double);
extern _Complex double (*pcd2) (double);
extern _Complex double (*pcd6) (double, float);
extern _Complex double (*pcd10) (double, double);
/* Macros for results checking. */
#define CHECK_RESULT(x, y) if ((x) != (y)) abort ()
#define CHECK_VOID_RESULT(x, y) CHECK_RESULT (((x), the_result), y)
/* Call functions through pointers and and check against expected results. */
void
test (void)
{
CHECK_VOID_RESULT (v0 (), 1.0);
CHECK_VOID_RESULT (v1 (1.0), 2.0);
CHECK_VOID_RESULT (v5 (5.0, 6.0), 12.0);
CHECK_VOID_RESULT (v9 (9.0, 10.0), 20.0);
CHECK_VOID_RESULT (v2 (2.0), 3.0);
CHECK_VOID_RESULT (v6 (6.0, 7.0), 14.0);
CHECK_VOID_RESULT (v10 (10.0, 11.0), 22.0);
CHECK_RESULT (f0 (), 1.0);
CHECK_RESULT (f1 (1.0), 2.0);
CHECK_RESULT (f5 (5.0, 6.0), 12.0);
CHECK_RESULT (f9 (9.0, 10.0), 20.0);
CHECK_RESULT (f2 (2.0), 3.0);
CHECK_RESULT (f6 (6.0, 7.0), 14.0);
CHECK_RESULT (f10 (10.0, 11.0), 22.0);
CHECK_RESULT (d0 (), 1.0);
CHECK_RESULT (d1 (1.0), 2.0);
CHECK_RESULT (d5 (5.0, 6.0), 12.0);
CHECK_RESULT (d9 (9.0, 10.0), 20.0);
CHECK_RESULT (d2 (2.0), 3.0);
CHECK_RESULT (d6 (6.0, 7.0), 14.0);
CHECK_RESULT (d10 (10.0, 11.0), 22.0);
CHECK_RESULT (cf0 (), 1.0 + 0.0i);
CHECK_RESULT (cf1 (1.0), 2.0 + 1.0i);
CHECK_RESULT (cf5 (5.0, 6.0), 12.0 + 5.0i);
CHECK_RESULT (cf9 (9.0, 10.0), 20.0 + 9.0i);
CHECK_RESULT (cf2 (2.0), 3.0 + 2.0i);
CHECK_RESULT (cf6 (6.0, 7.0), 14.0 + 6.0i);
CHECK_RESULT (cf10 (10.0, 11.0), 22.0 + 10.0i);
CHECK_RESULT (cd0 (), 1.0 + 0.0i);
CHECK_RESULT (cd1 (1.0), 2.0 + 1.0i);
CHECK_RESULT (cd5 (5.0, 6.0), 12.0 + 5.0i);
CHECK_RESULT (cd9 (9.0, 10.0), 20.0 + 9.0i);
CHECK_RESULT (cd2 (2.0), 3.0 + 2.0i);
CHECK_RESULT (cd6 (6.0, 7.0), 14.0 + 6.0i);
CHECK_RESULT (cd10 (10.0, 11.0), 22.0 + 10.0i);
CHECK_VOID_RESULT ((*pv0) (), 1.0);
CHECK_VOID_RESULT ((*pv1) (1.0), 2.0);
CHECK_VOID_RESULT ((*pv5) (5.0, 6.0), 12.0);
CHECK_VOID_RESULT ((*pv9) (9.0, 10.0), 20.0);
CHECK_VOID_RESULT ((*pv2) (2.0), 3.0);
CHECK_VOID_RESULT ((*pv6) (6.0, 7.0), 14.0);
CHECK_VOID_RESULT ((*pv10) (10.0, 11.0), 22.0);
CHECK_RESULT ((*pf0) (), 1.0);
CHECK_RESULT ((*pf1) (1.0), 2.0);
CHECK_RESULT ((*pf5) (5.0, 6.0), 12.0);
CHECK_RESULT ((*pf9) (9.0, 10.0), 20.0);
CHECK_RESULT ((*pf2) (2.0), 3.0);
CHECK_RESULT ((*pf6) (6.0, 7.0), 14.0);
CHECK_RESULT ((*pf10) (10.0, 11.0), 22.0);
CHECK_RESULT ((*pd0) (), 1.0);
CHECK_RESULT ((*pd1) (1.0), 2.0);
CHECK_RESULT ((*pd5) (5.0, 6.0), 12.0);
CHECK_RESULT ((*pd9) (9.0, 10.0), 20.0);
CHECK_RESULT ((*pd2) (2.0), 3.0);
CHECK_RESULT ((*pd6) (6.0, 7.0), 14.0);
CHECK_RESULT ((*pd10) (10.0, 11.0), 22.0);
CHECK_RESULT ((*pcf0) (), 1.0 + 0.0i);
CHECK_RESULT ((*pcf1) (1.0), 2.0 + 1.0i);
CHECK_RESULT ((*pcf5) (5.0, 6.0), 12.0 + 5.0i);
CHECK_RESULT ((*pcf9) (9.0, 10.0), 20.0 + 9.0i);
CHECK_RESULT ((*pcf2) (2.0), 3.0 + 2.0i);
CHECK_RESULT ((*pcf6) (6.0, 7.0), 14.0 + 6.0i);
CHECK_RESULT ((*pcf10) (10.0, 11.0), 22.0 + 10.0i);
CHECK_RESULT ((*pcd0) (), 1.0 + 0.0i);
CHECK_RESULT ((*pcd1) (1.0), 2.0 + 1.0i);
CHECK_RESULT ((*pcd5) (5.0, 6.0), 12.0 + 5.0i);
CHECK_RESULT ((*pcd9) (9.0, 10.0), 20.0 + 9.0i);
CHECK_RESULT ((*pcd2) (2.0), 3.0 + 2.0i);
CHECK_RESULT ((*pcd6) (6.0, 7.0), 14.0 + 6.0i);
CHECK_RESULT ((*pcd10) (10.0, 11.0), 22.0 + 10.0i);
}
/* All test functions return the sum of arguments, plus 1.
Void-returning functions put the result in the_result.
Complex-returning functions return their signature number as the
(constant) imaginary part of the result. */
double the_result;
void v0 (void) { the_result = 1.0; }
void v1 (float x) { the_result = 1.0 + x; }
void v5 (float x, float y) { the_result = 1.0 + x + y; }
void v9 (float x, double y) { the_result = 1.0 + x + y; }
void v2 (double x) { the_result = 1.0 + x; }
void v6 (double x, float y) { the_result = 1.0 + x + y; }
void v10 (double x, double y) { the_result = 1.0 + x + y; }
float f0 (void) { return 1.0; }
float f1 (float x) { return 1.0 + x; }
float f5 (float x, float y) { return 1.0 + x + y; }
float f9 (float x, double y) { return 1.0 + x + y; }
float f2 (double x) { return 1.0 + x; }
float f6 (double x, float y) { return 1.0 + x + y; }
float f10 (double x, double y) { return 1.0 + x + y; }
double d0 (void) { return 1.0; }
double d1 (float x) { return 1.0 + x; }
double d5 (float x, float y) { return 1.0 + x + y; }
double d9 (float x, double y) { return 1.0 + x + y; }
double d2 (double x) { return 1.0 + x; }
double d6 (double x, float y) { return 1.0 + x + y; }
double d10 (double x, double y) { return 1.0 + x + y; }
_Complex float cf0 (void) { return 1.0 + 0.0i; }
_Complex float cf1 (float x) { return 1.0 + x + 1.0i; }
_Complex float cf5 (float x, float y) { return 1.0 + x + y + 5.0i; }
_Complex float cf9 (float x, double y) { return 1.0 + x + y + 9.0i; }
_Complex float cf2 (double x) { return 1.0 + x + 2.0i; }
_Complex float cf6 (double x, float y) { return 1.0 + x + y + 6.0i; }
_Complex float cf10 (double x, double y) { return 1.0 + x + y + 10.0i; }
_Complex double cd0 (void) { return 1.0 + 0.0i; }
_Complex double cd1 (float x) { return 1.0 + x + 1.0i; }
_Complex double cd5 (float x, float y) { return 1.0 + x + y + 5.0i; }
_Complex double cd9 (float x, double y) { return 1.0 + x + y + 9.0i; }
_Complex double cd2 (double x) { return 1.0 + x + 2.0i; }
_Complex double cd6 (double x, float y) { return 1.0 + x + y + 6.0i; }
_Complex double cd10 (double x, double y) { return 1.0 + x + y + 10.0i; }
/* Declare and initialize all the pointer-to-function variables. */
void (*pv0) (void);
void (*pv1) (float);
void (*pv5) (float, float);
void (*pv9) (float, double);
void (*pv2) (double);
void (*pv6) (double, float);
void (*pv10) (double, double);
float (*pf0) (void);
float (*pf1) (float);
float (*pf5) (float, float);
float (*pf9) (float, double);
float (*pf2) (double);
float (*pf6) (double, float);
float (*pf10) (double, double);
double (*pd0) (void);
double (*pd1) (float);
double (*pd5) (float, float);
double (*pd9) (float, double);
double (*pd2) (double);
double (*pd6) (double, float);
double (*pd10) (double, double);
_Complex float (*pcf0) (void);
_Complex float (*pcf1) (float);
_Complex float (*pcf5) (float, float);
_Complex float (*pcf9) (float, double);
_Complex float (*pcf2) (double);
_Complex float (*pcf6) (double, float);
_Complex float (*pcf10) (double, double);
_Complex double (*pcd0) (void);
_Complex double (*pcd1) (float);
_Complex double (*pcd5) (float, float);
_Complex double (*pcd9) (float, double);
_Complex double (*pcd2) (double);
_Complex double (*pcd6) (double, float);
_Complex double (*pcd10) (double, double);
void
init (void)
{
pv0 = v0;
pv1 = v1;
pv5 = v5;
pv9 = v9;
pv2 = v2;
pv6 = v6;
pv10 = v10;
pf0 = f0;
pf1 = f1;
pf5 = f5;
pf9 = f9;
pf2 = f2;
pf6 = f6;
pf10 = f10;
pd0 = d0;
pd1 = d1;
pd5 = d5;
pd9 = d9;
pd2 = d2;
pd6 = d6;
pd10 = d10;
pcf0 = cf0;
pcf1 = cf1;
pcf5 = cf5;
pcf9 = cf9;
pcf2 = cf2;
pcf6 = cf6;
pcf10 = cf10;
pcd0 = cd0;
pcd1 = cd1;
pcd5 = cd5;
pcd9 = cd9;
pcd2 = cd2;
pcd6 = cd6;
pcd10 = cd10;
}
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