diff options
author | Richard Guenther <rguenther@suse.de> | 2010-06-30 12:33:30 +0000 |
---|---|---|
committer | Richard Guenther <rguenther@suse.de> | 2010-06-30 12:33:30 +0000 |
commit | 1a00539f6a8d8e30065f11f4bd7700e0189ff82c (patch) | |
tree | 8a0837186b3e5835baec053119aa90399c991088 /gcc/config | |
parent | 74ff248913c4923b008308cd6ea0068cc1b881f9 (diff) | |
parent | 648b57ef4306c09d5f73c2082fd43d27bd5706f0 (diff) |
2010-06-30 Richard Guenther <rguenther@suse.de>
Merge from trunk r161597.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/mem-ref2@161601 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
55 files changed, 700 insertions, 696 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 33a472ffa16..b6a83cba916 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -9742,7 +9742,7 @@ alpha_file_start (void) /* If emitting dwarf2 debug information, we cannot generate a .file directive to start the file, as it will conflict with dwarf2out file numbers. So it's only useful when emitting mdebug output. */ - targetm.file_start_file_directive = (write_symbols == DBX_DEBUG); + targetm.asm_file_start_file_directive = (write_symbols == DBX_DEBUG); #endif default_file_start (); diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 6235d9ff90a..c8590b9c782 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -703,15 +703,6 @@ extern int alpha_memory_latency; in a register. */ /* #define REG_PARM_STACK_SPACE */ -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 5127a123e31..9a4e360504b 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -530,14 +530,6 @@ extern enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER]; increase the stack frame size by this amount. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ -#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0 - /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should hold all necessary information about the function itself diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 685b5651bcb..9cb272c323e 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -434,8 +434,8 @@ static const struct attribute_spec arm_attribute_table[] = #define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack #ifdef TARGET_UNWIND_INFO -#undef TARGET_UNWIND_EMIT -#define TARGET_UNWIND_EMIT arm_unwind_emit +#undef TARGET_ASM_UNWIND_EMIT +#define TARGET_ASM_UNWIND_EMIT arm_unwind_emit /* EABI unwinding tables use a different format for the typeinfo tables. */ #undef TARGET_ASM_TTYPE diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 9066bbefb61..fcd1ef3d2eb 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1498,17 +1498,6 @@ do { \ /* Offset of first parameter from the argument pointer register value. */ #define FIRST_PARM_OFFSET(FNDECL) (TARGET_ARM ? 4 : 0) -/* Value is the number of byte of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the ARM, the caller does not pop any of its arguments that were passed - on the stack. */ -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0 - /* Define how to find the value returned by a library function assuming the value has mode MODE. */ #define LIBCALL_VALUE(MODE) \ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 1608929c95d..725d505ab5c 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1422,7 +1422,15 @@ (set_attr "predicable" "yes")] ) -;; Unnamed template to match long long multiply-accumulate (smlal) +(define_expand "maddsidi4" + [(set (match_operand:DI 0 "s_register_operand" "") + (plus:DI + (mult:DI + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) + (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))) + (match_operand:DI 3 "s_register_operand" "")))] + "TARGET_32BIT && arm_arch3m" + "") (define_insn "*mulsidi3adddi" [(set (match_operand:DI 0 "s_register_operand" "=&r") @@ -1518,7 +1526,15 @@ (set_attr "predicable" "yes")] ) -;; Unnamed template to match long long unsigned multiply-accumulate (umlal) +(define_expand "umaddsidi4" + [(set (match_operand:DI 0 "s_register_operand" "") + (plus:DI + (mult:DI + (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) + (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))) + (match_operand:DI 3 "s_register_operand" "")))] + "TARGET_32BIT && arm_arch3m" + "") (define_insn "*umulsidi3adddi" [(set (match_operand:DI 0 "s_register_operand" "=&r") @@ -1686,29 +1702,29 @@ (set_attr "predicable" "yes")] ) -(define_insn "*mulhisi3addsi" +(define_insn "maddhisi4" [(set (match_operand:SI 0 "s_register_operand" "=r") - (plus:SI (match_operand:SI 1 "s_register_operand" "r") + (plus:SI (match_operand:SI 3 "s_register_operand" "r") (mult:SI (sign_extend:SI - (match_operand:HI 2 "s_register_operand" "%r")) + (match_operand:HI 1 "s_register_operand" "%r")) (sign_extend:SI - (match_operand:HI 3 "s_register_operand" "r")))))] + (match_operand:HI 2 "s_register_operand" "r")))))] "TARGET_DSP_MULTIPLY" - "smlabb%?\\t%0, %2, %3, %1" + "smlabb%?\\t%0, %1, %2, %3" [(set_attr "insn" "smlaxy") (set_attr "predicable" "yes")] ) -(define_insn "*mulhidi3adddi" +(define_insn "*maddhidi4" [(set (match_operand:DI 0 "s_register_operand" "=r") (plus:DI - (match_operand:DI 1 "s_register_operand" "0") + (match_operand:DI 3 "s_register_operand" "0") (mult:DI (sign_extend:DI - (match_operand:HI 2 "s_register_operand" "%r")) + (match_operand:HI 1 "s_register_operand" "%r")) (sign_extend:DI - (match_operand:HI 3 "s_register_operand" "r")))))] + (match_operand:HI 2 "s_register_operand" "r")))))] "TARGET_DSP_MULTIPLY" - "smlalbb%?\\t%Q0, %R0, %2, %3" + "smlalbb%?\\t%Q0, %R0, %1, %2" [(set_attr "insn" "smlalxy") (set_attr "predicable" "yes")]) diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 398b412dd91..32ff27eedf4 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -376,8 +376,6 @@ enum reg_class { for POST_DEC targets (PR27386). */ /*#define PUSH_ROUNDING(NPUSHED) (NPUSHED)*/ -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) (function_arg (&(CUM), MODE, TYPE, NAMED)) typedef struct avr_args { diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h index a1bd556003e..367cd96dbc8 100644 --- a/gcc/config/bfin/bfin.h +++ b/gcc/config/bfin/bfin.h @@ -871,8 +871,6 @@ typedef struct { #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ (function_arg_advance (&CUM, MODE, TYPE, NAMED)) -#define RETURN_POPS_ARGS(FDECL, FUNTYPE, STKSIZE) 0 - /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 0dc18c7802b..05736c76165 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -2571,8 +2571,8 @@ cris_file_start (void) { /* These expressions can vary at run time, so we cannot put them into TARGET_INITIALIZER. */ - targetm.file_start_app_off = !(TARGET_PDEBUG || flag_print_asm_name); - targetm.file_start_file_directive = TARGET_ELF; + targetm.asm_file_start_app_off = !(TARGET_PDEBUG || flag_print_asm_name); + targetm.asm_file_start_file_directive = TARGET_ELF; default_file_start (); } diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index ae2bfee4757..4c685489a8c 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -859,8 +859,6 @@ enum reg_class #define ACCUMULATE_OUTGOING_ARGS 1 -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0 - /* Node: Register Arguments */ diff --git a/gcc/config/crx/crx.h b/gcc/config/crx/crx.h index 1d5cb87af3e..a6260f48aa2 100644 --- a/gcc/config/crx/crx.h +++ b/gcc/config/crx/crx.h @@ -313,8 +313,6 @@ enum reg_class #define PUSH_ROUNDING(BYTES) (((BYTES) + 3) & ~3) -#define RETURN_POPS_ARGS(FNDECL, FUNTYPE, SIZE) 0 - #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ ((rtx) crx_function_arg(&(CUM), (MODE), (TYPE), (NAMED))) diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h index 5e6237895b5..ed675b16e6a 100644 --- a/gcc/config/fr30/fr30.h +++ b/gcc/config/fr30/fr30.h @@ -568,41 +568,6 @@ enum reg_class proper. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* A C expression that should indicate the number of bytes of its own arguments - that a function pops on returning, or 0 if the function pops no arguments - and the caller must therefore pop them all after the function returns. - - FUNDECL is a C variable whose value is a tree node that describes the - function in question. Normally it is a node of type `FUNCTION_DECL' that - describes the declaration of the function. From this it is possible to - obtain the DECL_ATTRIBUTES of the function. - - FUNTYPE is a C variable whose value is a tree node that describes the - function in question. Normally it is a node of type `FUNCTION_TYPE' that - describes the data type of the function. From this it is possible to obtain - the data types of the value and arguments (if known). - - When a call to a library function is being considered, FUNTYPE will contain - an identifier node for the library function. Thus, if you need to - distinguish among various library functions, you can do so by their names. - Note that "library function" in this context means a function used to - perform arithmetic, whose name is known specially in the compiler and was - not mentioned in the C code being compiled. - - STACK-SIZE is the number of bytes of arguments passed on the stack. If a - variable number of bytes is passed, it is zero, and argument popping will - always be the responsibility of the calling function. - - On the VAX, all functions always pop their arguments, so the definition of - this macro is STACK-SIZE. On the 68000, using the standard calling - convention, no functions pop their arguments, so the value of the macro is - always 0 in this case. But an alternative calling convention is available - in which functions that take a fixed number of arguments pop them but other - functions (such as `printf') pop nothing (the caller pops all). When this - convention is in use, FUNTYPE is examined to determine whether a function - takes a fixed number of arguments. */ -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /*}}}*/ /*{{{ Function Arguments in Registers. */ diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h index 1bf8b6bb080..56db4e4a21e 100644 --- a/gcc/config/frv/frv.h +++ b/gcc/config/frv/frv.h @@ -1614,41 +1614,6 @@ typedef struct frv_stack { proper. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* A C expression that should indicate the number of bytes of its own arguments - that a function pops on returning, or 0 if the function pops no arguments - and the caller must therefore pop them all after the function returns. - - FUNDECL is a C variable whose value is a tree node that describes the - function in question. Normally it is a node of type `FUNCTION_DECL' that - describes the declaration of the function. From this it is possible to - obtain the DECL_ATTRIBUTES of the function. - - FUNTYPE is a C variable whose value is a tree node that describes the - function in question. Normally it is a node of type `FUNCTION_TYPE' that - describes the data type of the function. From this it is possible to obtain - the data types of the value and arguments (if known). - - When a call to a library function is being considered, FUNTYPE will contain - an identifier node for the library function. Thus, if you need to - distinguish among various library functions, you can do so by their names. - Note that "library function" in this context means a function used to - perform arithmetic, whose name is known specially in the compiler and was - not mentioned in the C code being compiled. - - STACK-SIZE is the number of bytes of arguments passed on the stack. If a - variable number of bytes is passed, it is zero, and argument popping will - always be the responsibility of the calling function. - - On the VAX, all functions always pop their arguments, so the definition of - this macro is STACK-SIZE. On the 68000, using the standard calling - convention, no functions pop their arguments, so the value of the macro is - always 0 in this case. But an alternative calling convention is available - in which functions that take a fixed number of arguments pop them but other - functions (such as `printf') pop nothing (the caller pops all). When this - convention is in use, FUNTYPE is examined to determine whether a function - takes a fixed number of arguments. */ -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /* The number of register assigned to holding function arguments. */ diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 1ce1585544e..4e0a3b6728e 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -536,17 +536,6 @@ enum reg_class { #define FIRST_PARM_OFFSET(FNDECL) 0 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the H8 the return does not pop anything. */ - -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0 - /* Definitions for register eliminations. This is an array of structures. Each structure initializes one pair diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 308f9eef5e8..4a0e3062212 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -180,16 +180,11 @@ extern void ix86_expand_truncdf_32 (rtx, rtx); #ifdef TREE_CODE extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); -extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, - tree, int); #endif /* TREE_CODE */ #endif /* RTX_CODE */ #ifdef TREE_CODE -extern int ix86_return_pops_args (tree, tree, int); - extern int ix86_data_alignment (tree, int); extern unsigned int ix86_local_alignment (tree, enum machine_mode, unsigned int); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9c308acf888..8a8b57aee5e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4865,7 +4865,7 @@ ix86_eax_live_at_start_p (void) The attribute stdcall is equivalent to RTD on a per module basis. */ -int +static int ix86_return_pops_args (tree fundecl, tree funtype, int size) { int rtd; @@ -5180,7 +5180,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ NULL. */ static enum machine_mode -type_natural_mode (const_tree type, CUMULATIVE_ARGS *cum) +type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum) { enum machine_mode mode = TYPE_MODE (type); @@ -5937,7 +5937,8 @@ construct_container (enum machine_mode mode, enum machine_mode orig_mode, static void function_arg_advance_32 (CUMULATIVE_ARGS *cum, enum machine_mode mode, - tree type, HOST_WIDE_INT bytes, HOST_WIDE_INT words) + const_tree type, HOST_WIDE_INT bytes, + HOST_WIDE_INT words) { switch (mode) { @@ -6025,7 +6026,7 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, enum machine_mode mode, static void function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, - tree type, HOST_WIDE_INT words, int named) + const_tree type, HOST_WIDE_INT words, bool named) { int int_nregs, sse_nregs; @@ -6061,9 +6062,13 @@ function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes, } } -void -function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, - tree type, int named) +/* Update the data in CUM to advance over an argument of mode MODE and + data type TYPE. (TYPE is null for libcalls where that information + may not be available.) */ + +static void +ix86_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, + const_tree type, bool named) { HOST_WIDE_INT bytes, words; @@ -6098,8 +6103,8 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, (otherwise it is an extra parameter matching an ellipsis). */ static rtx -function_arg_32 (CUMULATIVE_ARGS *cum, enum machine_mode mode, - enum machine_mode orig_mode, tree type, +function_arg_32 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, + enum machine_mode orig_mode, const_tree type, HOST_WIDE_INT bytes, HOST_WIDE_INT words) { static bool warnedsse, warnedmmx; @@ -6215,8 +6220,8 @@ function_arg_32 (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static rtx -function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, - enum machine_mode orig_mode, tree type, int named) +function_arg_64 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, + enum machine_mode orig_mode, const_tree type, bool named) { /* Handle a hidden AL argument containing number of registers for varargs x86-64 functions. */ @@ -6251,8 +6256,8 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static rtx -function_arg_ms_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, - enum machine_mode orig_mode, int named, +function_arg_ms_64 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, + enum machine_mode orig_mode, bool named, HOST_WIDE_INT bytes) { unsigned int regno; @@ -6298,9 +6303,19 @@ function_arg_ms_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, return gen_reg_or_parallel (mode, orig_mode, regno); } -rtx -function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode, - tree type, int named) +/* Return where to put the arguments to a function. + Return zero to push the argument on the stack, or a hard register in which to store the argument. + + MODE is the argument's machine mode. TYPE is the data type of the + argument. It is null for libcalls where that information may not be + available. CUM gives information about the preceding args and about + the function being called. NAMED is nonzero if this argument is a + named parameter (otherwise it is an extra parameter matching an + ellipsis). */ + +static rtx +ix86_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode omode, + const_tree type, bool named) { enum machine_mode mode = omode; HOST_WIDE_INT bytes, words; @@ -7033,7 +7048,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, For stdargs, we do want to skip the last named argument. */ next_cum = *cum; if (stdarg_p (fntype)) - function_arg_advance (&next_cum, mode, type, 1); + ix86_function_arg_advance (&next_cum, mode, type, true); if (cum->call_abi == MS_ABI) setup_incoming_varargs_ms_64 (&next_cum); @@ -30882,6 +30897,10 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG ix86_function_arg #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference #undef TARGET_INTERNAL_ARG_POINTER @@ -30896,6 +30915,8 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #define TARGET_STATIC_CHAIN ix86_static_chain #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init +#undef TARGET_RETURN_POPS_ARGS +#define TARGET_RETURN_POPS_ARGS ix86_return_pops_args #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 67f1f60f3a1..afe05f9f6db 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1542,26 +1542,6 @@ enum reg_class #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) \ (ix86_function_type_abi (FNTYPE) == MS_ABI) -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the 80386, the RTD insn may be used to pop them if the number - of args is fixed, but if the number is variable then the caller - must pop them all. RTD can't be used for library calls now - because the library is compiled with the Unix compiler. - Use of RTD is a selectable option, since it is incompatible with - standard Unix calling sequences. If the option is not selected, - the caller must always pop the args. - - The attribute stdcall is equivalent to RTD on a per module basis. */ - -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \ - ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE)) - /* Define how to find the value returned by a library function assuming the value has mode MODE. */ @@ -1611,29 +1591,6 @@ typedef struct ix86_args { #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL)) -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED)) - -/* Define where to put the arguments to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - function_arg (&(CUM), (MODE), (TYPE), (NAMED)) - /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 93843b365df..e361fd707ab 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -4729,6 +4729,7 @@ (set (match_operand:SSEMODEI24 2 "register_operand" "") (fix:SSEMODEI24 (match_dup 0)))] "TARGET_SHORTEN_X87_SSE + && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()) && peep2_reg_dead_p (2, operands[0])" [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))] "") @@ -17558,15 +17559,14 @@ ;; leal (%edx,%eax,4), %eax (define_peephole2 - [(parallel [(set (match_operand 0 "register_operand" "") + [(match_scratch:P 5 "r") + (parallel [(set (match_operand 0 "register_operand" "") (ashift (match_operand 1 "register_operand" "") (match_operand 2 "const_int_operand" ""))) (clobber (reg:CC FLAGS_REG))]) - (set (match_operand 3 "register_operand") - (match_operand 4 "x86_64_general_operand" "")) - (parallel [(set (match_operand 5 "register_operand" "") - (plus (match_operand 6 "register_operand" "") - (match_operand 7 "register_operand" ""))) + (parallel [(set (match_operand 3 "register_operand" "") + (plus (match_dup 0) + (match_operand 4 "x86_64_general_operand" ""))) (clobber (reg:CC FLAGS_REG))])] "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 /* Validate MODE for lea. */ @@ -17576,30 +17576,24 @@ || GET_MODE (operands[0]) == SImode || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) /* We reorder load and the shift. */ - && !rtx_equal_p (operands[1], operands[3]) - && !reg_overlap_mentioned_p (operands[0], operands[4]) - /* Last PLUS must consist of operand 0 and 3. */ - && !rtx_equal_p (operands[0], operands[3]) - && (rtx_equal_p (operands[3], operands[6]) - || rtx_equal_p (operands[3], operands[7])) - && (rtx_equal_p (operands[0], operands[6]) - || rtx_equal_p (operands[0], operands[7])) - /* The intermediate operand 0 must die or be same as output. */ - && (rtx_equal_p (operands[0], operands[5]) - || peep2_reg_dead_p (3, operands[0]))" - [(set (match_dup 3) (match_dup 4)) + && !reg_overlap_mentioned_p (operands[0], operands[4])" + [(set (match_dup 5) (match_dup 4)) (set (match_dup 0) (match_dup 1))] { - enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; + enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode; int scale = 1 << INTVAL (operands[2]); rtx index = gen_lowpart (Pmode, operands[1]); - rtx base = gen_lowpart (Pmode, operands[3]); - rtx dest = gen_lowpart (mode, operands[5]); + rtx base = gen_lowpart (Pmode, operands[5]); + rtx dest = gen_lowpart (mode, operands[3]); operands[1] = gen_rtx_PLUS (Pmode, base, gen_rtx_MULT (Pmode, index, GEN_INT (scale))); + operands[5] = base; if (mode != Pmode) - operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); + { + operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); + operands[5] = gen_rtx_SUBREG (mode, operands[5], 0); + } operands[0] = dest; }) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index d40747a7f1c..511ca155ab1 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -510,8 +510,8 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg -#undef TARGET_UNWIND_EMIT -#define TARGET_UNWIND_EMIT process_for_unwind_directive +#undef TARGET_ASM_UNWIND_EMIT +#define TARGET_ASM_UNWIND_EMIT process_for_unwind_directive #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index bf24f73f04e..d3821f6c6f4 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1042,12 +1042,6 @@ enum reg_class #define ACCUMULATE_OUTGOING_ARGS 1 -/* A C expression that should indicate the number of bytes of its own arguments - that a function pops on returning, or 0 if the function pops no arguments - and the caller must therefore pop them all after the function returns. */ - -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /* Function Arguments in Registers */ diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index 53a6b5cad04..07d4c2d864b 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -365,8 +365,6 @@ enum reg_class #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Function Arguments in Registers. */ diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h index 3a814576722..0bf37455627 100644 --- a/gcc/config/lm32/lm32.h +++ b/gcc/config/lm32/lm32.h @@ -273,8 +273,6 @@ enum reg_class #define ACCUMULATE_OUTGOING_ARGS 1 -#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0 - /*--------------------------------*/ /* Passing Arguments in Registers */ /*--------------------------------*/ diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h index a98005c78c1..8f7b720c696 100644 --- a/gcc/config/m32c/m32c.h +++ b/gcc/config/m32c/m32c.h @@ -503,7 +503,6 @@ enum reg_class #define PUSH_ARGS 1 #define PUSH_ROUNDING(N) m32c_push_rounding (N) -#define RETURN_POPS_ARGS(D,T,S) 0 #define CALL_POPS_ARGS(C) 0 /* Passing Arguments in Registers */ diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 28d06a4b23c..91d055bcb5b 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -823,14 +823,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; increase the stack frame size by this amount. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ -#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0 - /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should hold all necessary information about the function itself diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h index aef48a6e894..2ea80a76396 100644 --- a/gcc/config/m68hc11/m68hc11.h +++ b/gcc/config/m68hc11/m68hc11.h @@ -896,15 +896,6 @@ extern enum reg_class m68hc11_tmp_regs_class; stack pointer really advances by. No rounding or alignment needed for MC6811. */ #define PUSH_ROUNDING(BYTES) (BYTES) - -/* Value is 1 if returning from a function call automatically pops the - arguments described by the number-of-args field in the call. FUNTYPE is - the data type of the function (as a tree), or for a library call it is - an identifier node for the subroutine name. - - The standard MC6811 call, with arg count word, includes popping the - args as part of the call template. */ -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 /* Passing Arguments in Registers. */ diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 0ca5cd1d12a..253d621d074 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -153,6 +153,7 @@ static bool m68k_return_in_memory (const_tree, const_tree); #endif static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static void m68k_trampoline_init (rtx, tree, rtx); +static int m68k_return_pops_args (tree, tree, int); static rtx m68k_delegitimize_address (rtx); @@ -271,6 +272,9 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT m68k_trampoline_init +#undef TARGET_RETURN_POPS_ARGS +#define TARGET_RETURN_POPS_ARGS m68k_return_pops_args + #undef TARGET_DELEGITIMIZE_ADDRESS #define TARGET_DELEGITIMIZE_ADDRESS m68k_delegitimize_address @@ -6145,7 +6149,7 @@ m68k_sched_first_cycle_multipass_dfa_lookahead (void) return m68k_sched_issue_rate () - 1; } -/* Implementation of targetm.sched.md_init_global () hook. +/* Implementation of targetm.sched.init_global () hook. It is invoked once per scheduling pass and is used here to initialize scheduler constants. */ static void @@ -6253,7 +6257,7 @@ m68k_sched_md_finish_global (FILE *dump ATTRIBUTE_UNUSED, sched_branch_type = NULL; } -/* Implementation of targetm.sched.md_init () hook. +/* Implementation of targetm.sched.init () hook. It is invoked each time scheduler starts on the new block (basic block or extended basic block). */ static void @@ -6520,4 +6524,25 @@ m68k_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) FINALIZE_TRAMPOLINE (XEXP (m_tramp, 0)); } +/* On the 68000, the RTS insn cannot pop anything. + On the 68010, the RTD insn may be used to pop them if the number + of args is fixed, but if the number is variable then the caller + must pop them all. RTD can't be used for library calls now + because the library is compiled with the Unix compiler. + Use of RTD is a selectable option, since it is incompatible with + standard Unix calling sequences. If the option is not selected, + the caller must always pop the args. */ + +static int +m68k_return_pops_args (tree fundecl, tree funtype, int size) +{ + return ((TARGET_RTD + && (!fundecl + || TREE_CODE (fundecl) != IDENTIFIER_NODE) + && (TYPE_ARG_TYPES (funtype) == 0 + || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) + == void_type_node))) + ? size : 0); +} + #include "gt-m68k.h" diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 5787e8aa1fd..ac478619f73 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -534,21 +534,6 @@ extern enum reg_class regno_reg_class[]; #define FIRST_PARM_OFFSET(FNDECL) 8 -/* On the 68000, the RTS insn cannot pop anything. - On the 68010, the RTD insn may be used to pop them if the number - of args is fixed, but if the number is variable then the caller - must pop them all. RTD can't be used for library calls now - because the library is compiled with the Unix compiler. - Use of RTD is a selectable option, since it is incompatible with - standard Unix calling sequences. If the option is not selected, - the caller must always pop the args. */ -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - ((TARGET_RTD && (!(FUNDECL) || TREE_CODE (FUNDECL) != IDENTIFIER_NODE) \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) \ - ? (SIZE) : 0) - /* On the m68k the return value defaults to D0. */ #define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx_REG (TYPE_MODE (VALTYPE), D0_REG) diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h index 4f0ef1d7d6b..7421d5dbb85 100644 --- a/gcc/config/mcore/mcore.h +++ b/gcc/config/mcore/mcore.h @@ -540,16 +540,6 @@ extern const enum reg_class reg_class_from_letter[]; /* Offset of first parameter from the argument pointer register value. */ #define FIRST_PARM_OFFSET(FNDECL) 0 -/* Value is the number of byte of arguments automatically - popped when returning from a subroutine call. - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the MCore, the callee does not pop any of its arguments that were passed - on the stack. */ -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h index 9d286e33b94..d3af0734951 100644 --- a/gcc/config/mep/mep.h +++ b/gcc/config/mep/mep.h @@ -503,8 +503,6 @@ extern unsigned int mep_selected_isa; #define ACCUMULATE_OUTGOING_ARGS 1 -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /* The ABI is thus: Arguments are in $1, $2, $3, $4, stack. Arguments diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 4026bd73714..ea79eba2550 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2162,8 +2162,6 @@ enum reg_class #define STACK_BOUNDARY (TARGET_NEWABI ? 128 : 64) -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Symbolic macros for the registers used to return integer and floating point values. */ diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h index 2886443c66d..48551028d5b 100644 --- a/gcc/config/mmix/mmix.h +++ b/gcc/config/mmix/mmix.h @@ -586,8 +586,6 @@ enum reg_class #define ACCUMULATE_OUTGOING_ARGS 1 -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0 - /* Node: Register Arguments */ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index 12e78612014..1700f1a25be 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -492,15 +492,6 @@ enum reg_class { them whenever possible. */ #define CAN_DEBUG_WITHOUT_FP -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* We use d0/d1 for passing parameters, so allocate 8 bytes of space for a register flushback area. */ #define REG_PARM_STACK_SPACE(DECL) 8 diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h index 266a244c570..0a53b6b7216 100644 --- a/gcc/config/moxie/moxie.h +++ b/gcc/config/moxie/moxie.h @@ -453,8 +453,6 @@ enum reg_class /* All load operations zero extend. */ #define LOAD_EXTEND_OP(MEM) ZERO_EXTEND -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /* A C expression that is nonzero if X is a legitimate constant for an immediate operand on the target machine. */ #define LEGITIMATE_CONSTANT_P(X) 1 diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 8a18289b0d2..4eae700b077 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -553,14 +553,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void); ? (STACK_POINTER_OFFSET) \ : ((STACK_POINTER_OFFSET) - crtl->outgoing_args_size)) -/* Value is 1 if returning from a function call automatically - pops the arguments described by the number-of-args field in the call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Define how to find the value returned by a library function assuming the value has mode MODE. */ diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index 15eef844a34..006fb4cbd86 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -435,14 +435,6 @@ extern int current_first_parm_offset; */ #define FIRST_PARM_OFFSET(FNDECL) 4 -/* Value is 1 if returning from a function call automatically - pops the arguments described by the number-of-args field in the call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h index 7269fa062ad..b4aec727df5 100644 --- a/gcc/config/picochip/picochip.h +++ b/gcc/config/picochip/picochip.h @@ -406,9 +406,6 @@ extern const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER]; #define PUSH_ARGS 0 -/* Functions don't pop their args. */ -#define RETURN_POPS_ARGS(FNDECL, FNTYPE, STACK) 0 - /* Passing Arguments in Registers */ /* Store the offset of the next argument. */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 3b5ed65f5fe..6222bab60f4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1462,11 +1462,11 @@ static const struct attribute_spec rs6000_attribute_table[] = #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm -#undef TARGET_SUPPORT_VECTOR_MISALIGNMENT -#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \ +#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT +#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \ rs6000_builtin_support_vector_misalignment -#undef TARGET_VECTOR_ALIGNMENT_REACHABLE -#define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable +#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE +#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS rs6000_init_builtins diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3f37c4b4836..2ee3da18284 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1578,15 +1578,6 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */ found in the variable crtl->outgoing_args_size. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Define how to find the value returned by a library function assuming the value has mode MODE. */ diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md index d7a363ebb88..94e5f5630c2 100644 --- a/gcc/config/rx/predicates.md +++ b/gcc/config/rx/predicates.md @@ -50,9 +50,9 @@ ;; and a restricted subset of memory addresses are allowed. (define_predicate "rx_source_operand" - (match_code "const_int,reg,mem") + (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem") { - if (CONST_INT_P (op)) + if (CONSTANT_P (op)) return rx_is_legitimate_constant (op); if (! MEM_P (op)) diff --git a/gcc/config/rx/rx-modes.def b/gcc/config/rx/rx-modes.def new file mode 100644 index 00000000000..5936b672b6b --- /dev/null +++ b/gcc/config/rx/rx-modes.def @@ -0,0 +1,26 @@ +/* Definitions of target machine for GNU compiler, for ARM. + Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc. + Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) + and Martin Simmons (@harleqn.co.uk). + More major hacks by Richard Earnshaw (rearnsha@arm.com) + Minor hacks by Nick Clifton (nickc@cygnus.com) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +CC_MODE (CC_ZS); +CC_MODE (CC_ZSO); +CC_MODE (CC_ZSC); diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h index a2a28c12579..166290de5e7 100644 --- a/gcc/config/rx/rx-protos.h +++ b/gcc/config/rx/rx-protos.h @@ -31,6 +31,7 @@ extern int rx_initial_elimination_offset (int, int); extern void rx_set_optimization_options (void); #ifdef RTX_CODE +extern bool rx_compare_redundant (rtx); extern void rx_emit_stack_popm (rtx *, bool); extern void rx_emit_stack_pushm (rtx *); extern void rx_expand_epilogue (bool); diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index 8d9e462dd5c..2219efe8559 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -707,12 +707,6 @@ rx_gen_cond_branch_template (rtx condition, bool reversed) { enum rtx_code code = GET_CODE (condition); - if ((cc_status.flags & CC_NO_OVERFLOW) && ! rx_float_compare_mode) - gcc_assert (code != GT && code != GE && code != LE && code != LT); - - if ((cc_status.flags & CC_NO_CARRY) || rx_float_compare_mode) - gcc_assert (code != GEU && code != GTU && code != LEU && code != LTU); - if (reversed) { if (rx_float_compare_mode) @@ -1063,7 +1057,7 @@ rx_get_stack_layout (unsigned int * lowest, return; } - for (save_mask = high = low = 0, reg = 1; reg < FIRST_PSEUDO_REGISTER; reg++) + for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++) { if (df_regs_ever_live_p (reg) && (! call_used_regs[reg] @@ -1241,7 +1235,7 @@ rx_expand_prologue (void) if (mask) { /* Push registers in reverse order. */ - for (reg = FIRST_PSEUDO_REGISTER; reg --;) + for (reg = CC_REGNUM; reg --;) if (mask & (1 << reg)) { insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg))); @@ -1270,7 +1264,7 @@ rx_expand_prologue (void) { acc_low = acc_high = 0; - for (reg = 1; reg < FIRST_PSEUDO_REGISTER; reg ++) + for (reg = 1; reg < CC_REGNUM; reg ++) if (mask & (1 << reg)) { if (acc_low == 0) @@ -1543,7 +1537,8 @@ rx_expand_epilogue (bool is_sibcall) if (register_mask) { acc_low = acc_high = 0; - for (reg = 1; reg < FIRST_PSEUDO_REGISTER; reg ++) + + for (reg = 1; reg < CC_REGNUM; reg ++) if (register_mask & (1 << reg)) { if (acc_low == 0) @@ -1574,7 +1569,7 @@ rx_expand_epilogue (bool is_sibcall) if (register_mask) { - for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg ++) + for (reg = 0; reg < CC_REGNUM; reg ++) if (register_mask & (1 << reg)) emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg))); } @@ -1674,54 +1669,6 @@ rx_initial_elimination_offset (int from, int to) return stack_size; } -/* Update the status of the condition - codes (cc0) based on the given INSN. */ - -void -rx_notice_update_cc (rtx body, rtx insn) -{ - switch (get_attr_cc (insn)) - { - case CC_NONE: - /* Insn does not affect cc0 at all. */ - break; - case CC_CLOBBER: - /* Insn doesn't leave cc0 in a usable state. */ - CC_STATUS_INIT; - break; - case CC_SET_ZSOC: - /* The insn sets all the condition code bits. */ - CC_STATUS_INIT; - cc_status.value1 = SET_DEST (body); - break; - case CC_SET_ZSO: - /* Insn sets the Z,S and O flags, but not the C flag. */ - CC_STATUS_INIT; - cc_status.flags |= CC_NO_CARRY; - /* Do not set the value1 field in this case. The final_scan_insn() - function naively believes that if cc_status.value1 is set then - it can eliminate *any* comparison against that value, even if - the type of comparison cannot be satisfied by the range of flag - bits being set here. See gcc.c-torture/execute/20041210-1.c - for an example of this in action. */ - break; - case CC_SET_ZSC: - /* Insn sets the Z,S and C flags, but not the O flag. */ - CC_STATUS_INIT; - cc_status.flags |= CC_NO_OVERFLOW; - /* See comment above regarding cc_status.value1. */ - break; - case CC_SET_ZS: - /* Insn sets the Z and S flags, but not the O or C flags. */ - CC_STATUS_INIT; - cc_status.flags |= (CC_NO_CARRY | CC_NO_OVERFLOW); - /* See comment above regarding cc_status.value1. */ - break; - default: - gcc_unreachable (); - } -} - /* Decide if a variable should go into one of the small data sections. */ static bool @@ -2517,6 +2464,220 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain) } } + +static enum machine_mode +rx_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2) +{ + if (m1 == CCmode) + return m2; + if (m2 == CCmode) + return m1; + if (m1 == m2) + return m1; + if (m1 == CC_ZSmode) + return m1; + if (m2 == CC_ZSmode) + return m2; + return VOIDmode; +} + +#define CC_FLAG_S (1 << 0) +#define CC_FLAG_Z (1 << 1) +#define CC_FLAG_O (1 << 2) +#define CC_FLAG_C (1 << 3) + +static unsigned int +flags_needed_for_conditional (rtx conditional) +{ + switch (GET_CODE (conditional)) + { + case LE: + case GT: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O; + + case LEU: + case GTU: return CC_FLAG_Z | CC_FLAG_C; + + case LT: + case GE: return CC_FLAG_S | CC_FLAG_O; + + case LTU: + case GEU: return CC_FLAG_C; + + case EQ: + case NE: return CC_FLAG_Z; + + default: gcc_unreachable (); + } +} + +static unsigned int +flags_from_mode (enum machine_mode mode) +{ + switch (mode) + { + case CCmode: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C; + case CC_ZSmode: return CC_FLAG_S | CC_FLAG_Z; + case CC_ZSOmode: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O; + case CC_ZSCmode: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C; + default: gcc_unreachable (); + } +} + +/* Returns true if a compare insn is redundant because it + would only set flags that are already set correctly. */ + +bool +rx_compare_redundant (rtx cmp) +{ + unsigned int flags_needed; + unsigned int flags_set; + rtx next; + rtx prev; + rtx source; + rtx dest; + static rtx cc_reg = NULL_RTX; + + if (cc_reg == NULL_RTX) + cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); + + /* We can only eliminate compares against 0. */ + if (GET_CODE (XEXP (SET_SRC (PATTERN (cmp)), 1)) != CONST_INT + || INTVAL (XEXP (SET_SRC (PATTERN (cmp)), 1)) != 0) + return false; + + /* Locate the branch insn that follows the + compare and which tests the bits in the PSW. */ + next = cmp; + do + { + /* If we have found an insn that sets or clobbers the CC + register and it was not the IF_THEN_ELSE insn that we + are looking for, then the comparison is redundant. */ + if (next != cmp && reg_mentioned_p (cc_reg, PATTERN (next))) + return true; + + next = next_nonnote_insn (next); + + /* If we run out of insns without finding the + user then the comparison is unnecessary. */ + if (next == NULL_RTX) + return true; + + /* If we have found another comparison + insn then the first one is redundant. */ + if (INSN_P (next) + && GET_CODE (PATTERN (next)) == SET + && REG_P (SET_DEST (PATTERN (next))) + && REGNO (SET_DEST (PATTERN (next))) == CC_REGNUM) + return true; + + /* If we have found another arithmetic/logic insn that + sets the PSW flags then the comparison is redundant. */ + if (INSN_P (next) + && GET_CODE (PATTERN (next)) == PARALLEL + && GET_CODE (XVECEXP (PATTERN (next), 0, 1)) == SET + && REG_P (SET_DEST (XVECEXP (PATTERN (next), 0, 1))) + && REGNO (SET_DEST (XVECEXP (PATTERN (next), 0, 1))) == CC_REGNUM) + return true; + + /* If we have found an unconditional branch then the + PSW flags might be carried along with the jump, so + the comparison is necessary. */ + if (INSN_P (next) && JUMP_P (next)) + { + if (GET_CODE (PATTERN (next)) != SET) + /* If the jump does not involve setting the PC + then it is a return of some kind, and we know + that the comparison is not used. */ + return true; + + if (GET_CODE (SET_SRC (PATTERN (next))) != IF_THEN_ELSE) + return false; + } + } + while (! INSN_P (next) + || DEBUG_INSN_P (next) + || GET_CODE (PATTERN (next)) != SET + || GET_CODE (SET_SRC (PATTERN (next))) != IF_THEN_ELSE); + + flags_needed = flags_needed_for_conditional (XEXP (SET_SRC (PATTERN (next)), 0)); + + /* Now look to see if there was a previous + instruction which set the PSW bits. */ + source = XEXP (SET_SRC (PATTERN (cmp)), 0); + prev = cmp; + do + { + /* If this insn uses/sets/clobbers the CC register + and it is not the insn that we are looking for + below, then we must need the comparison. */ + if (prev != cmp && reg_mentioned_p (cc_reg, PATTERN (prev))) + return false; + + prev = prev_nonnote_insn (prev); + + if (prev == NULL_RTX) + return false; + + /* If we encounter an insn which changes the contents of + the register which is the source of the comparison then + we will definitely need the comparison. */ + if (INSN_P (prev) + && GET_CODE (PATTERN (prev)) == SET + && rtx_equal_p (SET_DEST (PATTERN (prev)), source)) + { + /* Unless this instruction is a simple register move + instruction. In which case we can continue our + scan backwards, but now using the *source* of this + set instruction. */ + if (REG_P (SET_SRC (PATTERN (prev)))) + source = SET_SRC (PATTERN (prev)); + /* We can also survive a sign-extension if the test is + for EQ/NE. Note the same does not apply to zero- + extension as this can turn a non-zero bit-pattern + into zero. */ + else if (flags_needed == CC_FLAG_Z + && GET_CODE (SET_SRC (PATTERN (prev))) == SIGN_EXTEND) + source = XEXP (SET_SRC (PATTERN (prev)), 0); + else + return false; + } + + /* A label means a possible branch into the + code here, so we have to stop scanning. */ + if (LABEL_P (prev)) + return false; + } + while (! INSN_P (prev) + || DEBUG_INSN_P (prev) + || GET_CODE (PATTERN (prev)) != PARALLEL + || GET_CODE (XVECEXP (PATTERN (prev), 0, 1)) != SET + || ! REG_P (SET_DEST (XVECEXP (PATTERN (prev), 0, 1))) + || REGNO (SET_DEST (XVECEXP (PATTERN (prev), 0, 1))) != CC_REGNUM); + + flags_set = flags_from_mode (GET_MODE (SET_DEST (XVECEXP (PATTERN (prev), 0, 1)))); + + dest = SET_DEST (XVECEXP (PATTERN (prev), 0, 0)); + /* The destination of the previous arithmetic/logic instruction + must match the source in the comparison operation. For registers + we ignore the mode as there may have been a sign-extension involved. */ + if (! rtx_equal_p (source, dest)) + { + if (REG_P (source) && REG_P (dest) && REGNO (dest) == REGNO (source)) + ; + else + return false; + } + + return ((flags_set & flags_needed) == flags_needed); +} + +static int +rx_memory_move_cost (enum machine_mode mode, enum reg_class regclass, bool in) +{ + return 2 + memory_move_secondary_cost (mode, regclass, in); +} + #undef TARGET_FUNCTION_VALUE #define TARGET_FUNCTION_VALUE rx_function_value @@ -2610,6 +2771,12 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain) #undef TARGET_PRINT_OPERAND_ADDRESS #define TARGET_PRINT_OPERAND_ADDRESS rx_print_operand_address +#undef TARGET_CC_MODES_COMPATIBLE +#define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible + +#undef TARGET_MEMORY_MOVE_COST +#define TARGET_MEMORY_MOVE_COST rx_memory_move_cost + struct gcc_target targetm = TARGET_INITIALIZER; /* #include "gt-rx.h" */ diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h index cb63951108b..b3a12690b08 100644 --- a/gcc/config/rx/rx.h +++ b/gcc/config/rx/rx.h @@ -154,7 +154,6 @@ extern enum rx_cpu_types rx_cpu_type; #define MOVE_MAX 4 #define STARTING_FRAME_OFFSET 0 -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 #define LEGITIMATE_CONSTANT_P(X) rx_is_legitimate_constant (X) @@ -208,7 +207,7 @@ enum reg_class #define BASE_REG_CLASS GR_REGS #define INDEX_REG_CLASS GR_REGS -#define FIRST_PSEUDO_REGISTER 16 +#define FIRST_PSEUDO_REGISTER 17 #define REGNO_REG_CLASS(REGNO) ((REGNO) < FIRST_PSEUDO_REGISTER \ ? GR_REGS : NO_REGS) @@ -220,6 +219,7 @@ enum reg_class #define STATIC_CHAIN_REGNUM 8 #define TRAMPOLINE_TEMP_REGNUM 9 #define STRUCT_VAL_REGNUM 15 +#define CC_REGNUM 16 /* This is the register which is used to hold the address of the start of the small data area, if that feature is being used. Note - this @@ -246,12 +246,12 @@ enum reg_class #define FIXED_REGISTERS \ { \ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \ } #define CALL_USED_REGISTERS \ { \ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 \ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 \ } #define CONDITIONAL_REGISTER_USAGE \ @@ -352,7 +352,7 @@ typedef unsigned int CUMULATIVE_ARGS; #define REGISTER_NAMES \ { \ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" \ + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc" \ }; #define ADDITIONAL_REGISTER_NAMES \ @@ -610,9 +610,6 @@ typedef unsigned int CUMULATIVE_ARGS; they contain are always computed between two same-section symbols. */ #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic) -#define CC_NO_CARRY 0400 -#define NOTICE_UPDATE_CC(EXP, INSN) rx_notice_update_cc (EXP, INSN) - extern int rx_float_compare_mode; /* This is a version of REG_P that also returns TRUE for SUBREGs. */ @@ -647,3 +644,16 @@ extern int rx_float_compare_mode; /* This macro is used to decide when RX FPU instructions can be used. */ #define ALLOW_RX_FPU_INSNS (TARGET_USE_FPU) + +#define BRANCH_COST(SPEED,PREDICT) 1 +#define REGISTER_MOVE_COST(MODE,FROM,TO) 2 + +#define SELECT_CC_MODE(OP,X,Y) \ + (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CC_ZSmode : \ + (GET_CODE (X) == PLUS || GET_CODE (X) == MINUS ? CC_ZSCmode : \ + (GET_CODE (X) == ABS ? CC_ZSOmode : \ + (GET_CODE (X) == AND || GET_CODE (X) == NOT || GET_CODE (X) == IOR \ + || GET_CODE (X) == XOR || GET_CODE (X) == ROTATE \ + || GET_CODE (X) == ROTATERT || GET_CODE (X) == ASHIFTRT \ + || GET_CODE (X) == LSHIFTRT || GET_CODE (X) == ASHIFT ? CC_ZSmode : \ + CCmode)))) diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index 6fe25259472..aeba85ffe39 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -47,6 +47,7 @@ (define_constants [ (SP_REG 0) + (CC_REG 16) (UNSPEC_LOW_REG 0) (UNSPEC_HIGH_REG 1) @@ -86,14 +87,6 @@ ] ) -;; Condition code settings: -;; none - insn does not affect the condition code bits -;; set_zs - insn sets z,s to usable values; -;; set_zso - insn sets z,s,o to usable values; -;; set_zsoc - insn sets z,s,o,c to usable values; -;; clobber - value of cc0 is unknown -(define_attr "cc" "none,set_zs,set_zso,set_zsoc,set_zsc,clobber" (const_string "none")) - (define_attr "length" "" (const_int 8)) (include "predicates.md") @@ -156,77 +149,120 @@ ;; Comparisons +;; Note - we do not specify the two instructions necessary to perform +;; a compare-and-branch in the cbranchsi4 pattern because that would +;; allow the comparison to be moved away from the jump before the reload +;; pass has completed. That would be problematical because reload can +;; generate ADDSI3 instructions which would corrupt the PSW flags. + (define_expand "cbranchsi4" - [(set (cc0) (compare:CC (match_operand:SI 1 "register_operand") - (match_operand:SI 2 "rx_source_operand"))) - (set (pc) - (if_then_else (match_operator:SI 0 "comparison_operator" - [(cc0) (const_int 0)]) + [(set (pc) + (if_then_else (match_operator:SI 0 "comparison_operator" + [(match_operand:SI 1 "register_operand") + (match_operand:SI 2 "rx_source_operand")]) (label_ref (match_operand 3 "")) - (pc)))] + (pc))) + ] "" "" ) +(define_insn_and_split "*cbranchsi4_<code>" + [(set (pc) + (if_then_else (most_cond:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "rx_source_operand" "riQ")) + (label_ref (match_operand 2 "" "")) + (pc))) + ] + "" + "#" + "reload_completed" + [(const_int 0)] + " + /* We contstruct the split by hand as otherwise the JUMP_LABEL + attribute is not set correctly on the jump insn. */ + emit_insn (gen_cmpsi (operands[0], operands[1])); + + emit_jump_insn (gen_conditional_branch (operands[2], + gen_rtx_fmt_ee (<most_cond:CODE>, CCmode, + gen_rtx_REG (CCmode, CC_REG), const0_rtx))); + " +) + (define_expand "cbranchsf4" - [(set (cc0) (compare:CC (match_operand:SF 1 "register_operand") - (match_operand:SF 2 "rx_source_operand"))) - (set (pc) - (if_then_else (match_operator:SI 0 "comparison_operator" - [(cc0) (const_int 0)]) + [(set (pc) + (if_then_else (match_operator:SF 0 "comparison_operator" + [(match_operand:SF 1 "register_operand") + (match_operand:SF 2 "rx_source_operand")]) (label_ref (match_operand 3 "")) - (pc)))] - "ALLOW_RX_FPU_INSNS && (cfun == NULL || !cfun->can_throw_non_call_exceptions)" + (pc))) + ] + "ALLOW_RX_FPU_INSNS" "" ) -;; The TST instruction is not used as it does not set the Carry flag, -;; so for example, the LessThan comparison cannot be tested. -;; -;; (define_insn "tstsi" -;; [(set (cc0) -;; (match_operand:SI 0 "rx_source_operand" "r,i,Q")))] -;; "" -;; { -;; rx_float_compare_mode = false; -;; return "tst\t%Q0"; -;; } -;; [(set_attr "cc" "set_zs") -;; (set_attr "timings" "11,11,33") -;; (set_attr "length" "3,7,6")] -;; ) +(define_insn_and_split "*cbranchsf4_<code>" + [(set (pc) + (if_then_else (most_cond:SF (match_operand:SF 0 "register_operand" "r") + (match_operand:SF 1 "rx_source_operand" "rFiQ")) + (label_ref (match_operand 2 "" "")) + (pc))) + ] + "ALLOW_RX_FPU_INSNS" + "#" + "&& reload_completed" + [(const_int 0)] + " + /* We contstruct the split by hand as otherwise the JUMP_LABEL + attribute is not set correctly on the jump insn. */ + emit_insn (gen_cmpsf (operands[0], operands[1])); + + emit_jump_insn (gen_conditional_branch (operands[2], + gen_rtx_fmt_ee (<most_cond:CODE>, CCmode, + gen_rtx_REG (CCmode, CC_REG), const0_rtx))); + " +) + +(define_insn "tstsi" + [(set (reg:CC_ZS CC_REG) + (compare:CC_ZS (and:SI (match_operand:SI 0 "register_operand" "r,r,r") + (match_operand:SI 1 "rx_source_operand" "r,i,Q")) + (const_int 0)))] + "" + { + rx_float_compare_mode = false; + return "tst\t%Q1, %0"; + } + [(set_attr "timings" "11,11,33") + (set_attr "length" "3,7,6")] +) (define_insn "cmpsi" - [(set (cc0) (compare:CC - (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r") - (match_operand:SI 1 "rx_source_operand" - "r,Uint04,Int08,Sint16,Sint24,i,Q")))] + [(set (reg:CC CC_REG) + (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r") + (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))] "" { rx_float_compare_mode = false; + if (rx_compare_redundant (insn)) + return "; Compare Eliminated: cmp %Q1, %0"; return "cmp\t%Q1, %0"; } - [(set_attr "cc" "set_zsoc") - (set_attr "timings" "11,11,11,11,11,11,33") + [(set_attr "timings" "11,11,11,11,11,11,33") (set_attr "length" "2,2,3,4,5,6,5")] ) -;; This pattern is disabled if the function can throw non-call exceptions, -;; because it could generate a floating point exception, which would -;; introduce an edge into the flow graph between this insn and the -;; conditional branch insn to follow, thus breaking the cc0 relationship. -;; Run the g++ test g++.dg/eh/080514-1.C to see this happen. +;; ??? g++.dg/eh/080514-1.C to see this happen. (define_insn "cmpsf" - [(set (cc0) - (compare:CC (match_operand:SF 0 "register_operand" "r,r,r") - (match_operand:SF 1 "rx_source_operand" "r,i,Q")))] - "ALLOW_RX_FPU_INSNS && (cfun == NULL || !cfun->can_throw_non_call_exceptions)" + [(set (reg:CC_ZSO CC_REG) + (compare:CC_ZSO (match_operand:SF 0 "register_operand" "r,r,r") + (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))] + "ALLOW_RX_FPU_INSNS" { rx_float_compare_mode = true; return "fcmp\t%1, %0"; } - [(set_attr "cc" "set_zso") - (set_attr "timings" "11,11,33") + [(set_attr "timings" "11,11,33") (set_attr "length" "3,7,5")] ) @@ -234,17 +270,17 @@ (define_expand "b<code>" [(set (pc) - (if_then_else (most_cond (cc0) (const_int 0)) + (if_then_else (most_cond (reg:CC CC_REG) (const_int 0)) (label_ref (match_operand 0)) (pc)))] "" "" ) -(define_insn "*conditional_branch" +(define_insn "conditional_branch" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) + [(reg:CC CC_REG) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] "" @@ -253,14 +289,13 @@ } [(set_attr "length" "8") ;; This length is wrong, but it is ;; too hard to compute statically. - (set_attr "timings" "33") ;; The timing assumes that the branch is taken. - (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. + (set_attr "timings" "33")] ;; The timing assumes that the branch is taken. ) (define_insn "*reveresed_conditional_branch" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) + [(reg:CC CC_REG) (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] "" @@ -269,38 +304,37 @@ } [(set_attr "length" "8") ;; This length is wrong, but it is ;; too hard to compute statically. - (set_attr "timings" "33") ;; The timing assumes that the branch is taken. - (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. + (set_attr "timings" "33")] ;; The timing assumes that the branch is taken. ) (define_insn "jump" - [(set (pc) (label_ref (match_operand 0 "" "")))] + [(set (pc) + (label_ref (match_operand 0 "" "")))] "" "bra\t%0" [(set_attr "length" "4") - (set_attr "timings" "33") - (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. + (set_attr "timings" "33")] ) (define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "register_operand" "r"))] + [(set (pc) + (match_operand:SI 0 "register_operand" "r"))] "" "jmp\t%0" [(set_attr "length" "2") - (set_attr "timings" "33") - (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong. + (set_attr "timings" "33")] ) (define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "register_operand" "r")) + [(set (pc) + (match_operand:SI 0 "register_operand" "r")) (use (label_ref (match_operand 1 "" "")))] "" { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0" : "\n1:\tbra\t%0") : "jmp\t%0"; } - [(set_attr "cc" "clobber") ;; FIXME: This clobber is wrong. - (set_attr "timings" "33") + [(set_attr "timings" "33") (set_attr "length" "2")] ) @@ -324,11 +358,10 @@ ) (define_insn "pop_and_return" - [(match_parallel 1 "rx_rtsd_vector" + [(match_parallel 1 "rx_rtsd_vector" [(set:SI (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) - (match_operand:SI - 0 "const_int_operand" "n")))])] + (match_operand:SI 0 "const_int_operand" "n")))])] "reload_completed" { rx_emit_stack_popm (operands, false); @@ -385,13 +418,13 @@ (define_insn "call_internal" [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol")) - (match_operand:SI 1 "general_operand" "g,g"))] + (match_operand:SI 1 "general_operand" "g,g")) + (clobber (reg:CC CC_REG))] "" "@ jsr\t%0 bsr\t%A0" [(set_attr "length" "2,4") - (set_attr "cc" "clobber") (set_attr "timings" "33")] ) @@ -413,13 +446,13 @@ (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=r,r") (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol")) - (match_operand:SI 2 "general_operand" "g,g")))] + (match_operand:SI 2 "general_operand" "g,g"))) + (clobber (reg:CC CC_REG))] "" "@ jsr\t%1 bsr\t%A1" [(set_attr "length" "2,4") - (set_attr "cc" "clobber") (set_attr "timings" "33")] ) @@ -564,11 +597,10 @@ ) (define_insn "stack_pushm" - [(match_parallel 1 "rx_store_multiple_vector" + [(match_parallel 1 "rx_store_multiple_vector" [(set:SI (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) - (match_operand:SI - 0 "const_int_operand" "n")))])] + (match_operand:SI 0 "const_int_operand" "n")))])] "reload_completed" { rx_emit_stack_pushm (operands); @@ -591,11 +623,10 @@ ) (define_insn "stack_popm" - [(match_parallel 1 "rx_load_multiple_vector" + [(match_parallel 1 "rx_load_multiple_vector" [(set:SI (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) - (match_operand:SI - 0 "const_int_operand" "n")))])] + (match_operand:SI 0 "const_int_operand" "n")))])] "reload_completed" { rx_emit_stack_popm (operands, true); @@ -605,29 +636,29 @@ (set_attr "timings" "45")] ;; The timing is a guesstimate average timing. ) +;; FIXME: Add memory destination options ? (define_insn "cstoresi4" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") - (match_operator:SI - 1 "comparison_operator" - [(match_operand:SI - 2 "register_operand" "r,r,r,r,r,r,r") - (match_operand:SI - 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (match_operator:SI 1 "comparison_operator" + [(match_operand:SI 2 "register_operand" "r,r,r,r,r,r,r") + (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")])) + (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0. "" { rx_float_compare_mode = false; return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0"; } - [(set_attr "cc" "clobber") ;; Because cc0 is set based on comparing ops 2 & 3 not the value in op 0. - (set_attr "timings" "22,22,22,22,22,22,44") + [(set_attr "timings" "22,22,22,22,22,22,44") (set_attr "length" "5,5,6,7,8,9,8")] ) (define_expand "movsicc" - [(set (match_operand:SI 0 "register_operand") - (if_then_else:SI (match_operand:SI 1 "comparison_operator") - (match_operand:SI 2 "nonmemory_operand") - (match_operand:SI 3 "immediate_operand")))] + [(parallel + [(set (match_operand:SI 0 "register_operand") + (if_then_else:SI (match_operand:SI 1 "comparison_operator") + (match_operand:SI 2 "nonmemory_operand") + (match_operand:SI 3 "immediate_operand"))) + (clobber (reg:CC CC_REG))])] ;; See cstoresi4 "" { if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE) @@ -638,22 +669,18 @@ ) (define_insn "*movsieq" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (if_then_else:SI (eq (match_operand:SI - 3 "register_operand" "r,r,r") - (match_operand:SI - 4 "rx_source_operand" "riQ,riQ,riQ")) - (match_operand:SI - 1 "nonmemory_operand" "0,i,r") - (match_operand:SI - 2 "immediate_operand" "i,i,i")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r") + (if_then_else:SI (eq (match_operand:SI 3 "register_operand" "r,r,r") + (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ")) + (match_operand:SI 1 "nonmemory_operand" "0,i,r") + (match_operand:SI 2 "immediate_operand" "i,i,i"))) + (clobber (reg:CC CC_REG))] ;; See cstoresi4 "" "@ cmp\t%Q4, %Q3\n\tstnz\t%2, %0 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0" - [(set_attr "cc" "clobber") ;; See cstoresi4 - (set_attr "length" "13,19,15") + [(set_attr "length" "13,19,15") (set_attr "timings" "22,33,33")] ) @@ -662,14 +689,14 @@ (if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r") (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ")) (match_operand:SI 1 "nonmemory_operand" "0,i,r") - (match_operand:SI 2 "immediate_operand" "i,i,i")))] + (match_operand:SI 2 "immediate_operand" "i,i,i"))) + (clobber (reg:CC CC_REG))] ;; See cstoresi4 "" "@ cmp\t%Q4, %Q3\n\tstz\t%2, %0 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0" - [(set_attr "cc" "clobber") ;; See cstoresi4 - (set_attr "length" "13,19,15") + [(set_attr "length" "13,19,15") (set_attr "timings" "22,33,33")] ) @@ -677,24 +704,24 @@ (define_insn "abssi2" [(set (match_operand:SI 0 "register_operand" "=r,r") - (abs:SI (match_operand:SI 1 "register_operand" "0,r")))] + (abs:SI (match_operand:SI 1 "register_operand" "0,r"))) + (set (reg:CC_ZSO CC_REG) + (compare:CC_ZSO (abs:SI (match_dup 1)) + (const_int 0)))] "" "@ abs\t%0 abs\t%1, %0" - [(set_attr "cc" "set_zso") - (set_attr "length" "2,3")] + [(set_attr "length" "2,3")] ) (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" - "=r,r,r,r,r,r,r,r,r,r,r,r,r") - (plus:SI (match_operand:SI - 1 "register_operand" - "%0,0,0,0,0,0,0,r,r,r,r,r,0") - (match_operand:SI - 2 "rx_source_operand" - "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,r,Sint08,Sint16,Sint24,i,Q")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r") + (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0") + (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q"))) + (set (reg:CC_ZSC CC_REG) ;; See subsi3 + (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ add\t%2, %0 @@ -704,35 +731,38 @@ add\t%2, %0 add\t%2, %0 add\t%2, %0 + add\t%1, %0 add\t%2, %1, %0 add\t%2, %1, %0 add\t%2, %1, %0 add\t%2, %1, %0 add\t%2, %1, %0 add\t%Q2, %0" - [(set_attr "cc" "set_zsc") ;; See subsi3 - (set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,33") - (set_attr "length" "2,2,2,3,4,5,6,3,3,4,5,6,5")] + [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33") + (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")] ) (define_insn "adddi3" [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0") (match_operand:DI 2 "rx_source_operand" - "r,Sint08,Sint16,Sint24,i,Q")))] + "r,Sint08,Sint16,Sint24,i,Q"))) + (set (reg:CC_ZSC CC_REG) ;; See subsi3 + (compare:CC_ZSC (plus:DI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "add\t%L2, %L0\n\tadc\t%H2, %H0" - [(set_attr "cc" "set_zsc") ;; See subsi3 - (set_attr "timings" "22,22,22,22,22,44") + [(set_attr "timings" "22,22,22,22,22,44") (set_attr "length" "5,7,9,11,13,11")] ) (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") - (match_operand:SI - 2 "rx_source_operand" - "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))] + (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ and\t%2, %0 @@ -744,8 +774,7 @@ and\t%1, %0 and\t%2, %1, %0 and\t%Q2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "11,11,11,11,11,11,11,33,33") + [(set_attr "timings" "11,11,11,11,11,11,11,33,33") (set_attr "length" "2,2,3,4,5,6,2,5,5")] ) @@ -770,12 +799,11 @@ (define_insn "divsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0") - (match_operand:SI - 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))] + (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))) + (clobber (reg:CC CC_REG))] "" "div\t%Q2, %0" - [(set_attr "cc" "clobber") - (set_attr "timings" "1111") ;; Strictly speaking the timing should be + [(set_attr "timings" "1111") ;; Strictly speaking the timing should be ;; 2222, but that is a worst case sceanario. (set_attr "length" "3,4,5,6,7,6")] ) @@ -783,12 +811,11 @@ (define_insn "udivsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0") - (match_operand:SI - 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))] + (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))) + (clobber (reg:CC CC_REG))] "" "divu\t%Q2, %0" - [(set_attr "cc" "clobber") - (set_attr "timings" "1010") ;; Strictly speaking the timing should be + [(set_attr "timings" "1010") ;; Strictly speaking the timing should be ;; 2020, but that is a worst case sceanario. (set_attr "length" "3,4,5,6,7,6")] ) @@ -816,12 +843,9 @@ ;; mulsidi3 pattern. Immediate mode addressing is not supported ;; because gcc cannot handle the expression: (zero_extend (const_int)). (define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" - "=r,r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" - "%0,0")) - (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" - "r,Q"))))] + [(set (match_operand:DI 0 "register_operand" "=r,r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0")) + (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))] "! TARGET_BIG_ENDIAN_DATA" "emulu\t%Q2, %0" [(set_attr "length" "3,6") @@ -872,33 +896,39 @@ (define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=r,r") - (neg:SI (match_operand:SI 1 "register_operand" "0,r")))] + (neg:SI (match_operand:SI 1 "register_operand" "0,r"))) + (set (reg:CC CC_REG) + (compare:CC (neg:SI (match_dup 1)) + (const_int 0)))] ;; The NEG instruction does not comply with -fwrapv semantics. ;; See gcc.c-torture/execute/pr22493-1.c for an example of this. "! flag_wrapv" "@ neg\t%0 neg\t%1, %0" - [(set_attr "length" "2,3") - (set_attr "cc" "set_zsoc")] + [(set_attr "length" "2,3")] ) (define_insn "one_cmplsi2" [(set (match_operand:SI 0 "register_operand" "=r,r") - (not:SI (match_operand:SI 1 "register_operand" "0,r")))] + (not:SI (match_operand:SI 1 "register_operand" "0,r"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (not:SI (match_dup 1)) + (const_int 0)))] "" "@ not\t%0 not\t%1, %0" - [(set_attr "cc" "set_zs") - (set_attr "length" "2,3")] + [(set_attr "length" "2,3")] ) (define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") - (match_operand:SI 2 "rx_source_operand" - "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))] + (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (ior:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ or\t%2, %0 @@ -910,74 +940,89 @@ or\t%1, %0 or\t%2, %1, %0 or\t%Q2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "11,11,11,11,11,11,11,11,33") + [(set_attr "timings" "11,11,11,11,11,11,11,11,33") (set_attr "length" "2,2,3,4,5,6,2,3,5")] ) (define_insn "rotlsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotate:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "rx_shift_operand" "rn")))] + (match_operand:SI 2 "rx_shift_operand" "rn"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (rotate:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "rotl\t%2, %0" - [(set_attr "cc" "set_zs") - (set_attr "length" "3")] + [(set_attr "length" "3")] ) (define_insn "rotrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotatert:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "rx_shift_operand" "rn")))] + (match_operand:SI 2 "rx_shift_operand" "rn"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (rotatert:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "rotr\t%2, %0" - [(set_attr "cc" "set_zs") - (set_attr "length" "3")] + [(set_attr "length" "3")] ) (define_insn "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") - (match_operand:SI 2 "rx_shift_operand" "r,n,n")))] + (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (ashiftrt:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ shar\t%2, %0 shar\t%2, %0 shar\t%2, %1, %0" - [(set_attr "cc" "set_zs") - (set_attr "length" "3,2,3")] + [(set_attr "length" "3,2,3")] ) (define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") - (match_operand:SI 2 "rx_shift_operand" "r,n,n")))] + (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (lshiftrt:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ shlr\t%2, %0 shlr\t%2, %0 shlr\t%2, %1, %0" - [(set_attr "cc" "set_zs") - (set_attr "length" "3,2,3")] + [(set_attr "length" "3,2,3")] ) (define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r") - (match_operand:SI 2 "rx_shift_operand" "r,n,n")))] + (match_operand:SI 2 "rx_shift_operand" "r,n,n"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (ashift:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ shll\t%2, %0 shll\t%2, %0 shll\t%2, %1, %0" - [(set_attr "cc" "set_zs") - (set_attr "length" "3,2,3")] + [(set_attr "length" "3,2,3")] ) (define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0") - (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))] + (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q"))) + (set (reg:CC_ZSC CC_REG) + ;; Note - we do not acknowledge that the SUB instruction sets the Overflow + ;; flag because its interpretation is different from comparing the result + ;; against zero. Compile and run gcc.c-torture/execute/cmpsi-1.c to see this. + (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "@ sub\t%2, %0 @@ -985,22 +1030,20 @@ add\t%N2, %0 sub\t%2, %1, %0 sub\t%Q2, %0" - [(set_attr "cc" "set_zsc") ;; Note - we do not acknowledge that the SUB - ;; instruction sets the Overflow flag because its interpretation is - ;; different from comparing the result against zero. Compile and run - ;; gcc.c-torture/execute/cmpsi-1.c to see this. - (set_attr "timings" "11,11,11,11,33") + [(set_attr "timings" "11,11,11,11,33") (set_attr "length" "2,2,6,3,5")] ) (define_insn "subdi3" [(set (match_operand:DI 0 "register_operand" "=r,r") (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "rx_source_operand" "r,Q")))] + (match_operand:DI 2 "rx_source_operand" "r,Q"))) + (set (reg:CC_ZSC CC_REG) ;; See subsi3 + (compare:CC_ZSC (minus:DI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "sub\t%L2, %L0\n\tsbb\t%H2, %H0" - [(set_attr "cc" "set_zsc") ;; See subsi3 - (set_attr "timings" "22,44") + [(set_attr "timings" "22,44") (set_attr "length" "5,11")] ) @@ -1008,11 +1051,13 @@ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") (match_operand:SI 2 "rx_source_operand" - "r,Sint08,Sint16,Sint24,i,Q")))] + "r,Sint08,Sint16,Sint24,i,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (xor:SI (match_dup 1) (match_dup 2)) + (const_int 0)))] "" "xor\t%Q2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "11,11,11,11,11,33") + [(set_attr "timings" "11,11,11,11,11,33") (set_attr "length" "3,4,5,6,7,6")] ) @@ -1021,64 +1066,76 @@ (define_insn "addsf3" [(set (match_operand:SF 0 "register_operand" "=r,r,r") (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0") - (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] + (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (plus:SF (match_dup 1) (match_dup 2)) + (const_int 0)))] "ALLOW_RX_FPU_INSNS" "fadd\t%2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "44,44,66") + [(set_attr "timings" "44,44,66") (set_attr "length" "3,7,5")] ) (define_insn "divsf3" [(set (match_operand:SF 0 "register_operand" "=r,r,r") (div:SF (match_operand:SF 1 "register_operand" "0,0,0") - (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] + (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (div:SF (match_dup 1) (match_dup 2)) + (const_int 0)))] "ALLOW_RX_FPU_INSNS" "fdiv\t%2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "1616,1616,1818") + [(set_attr "timings" "1616,1616,1818") (set_attr "length" "3,7,5")] ) (define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=r,r,r") (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0") - (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] + (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (mult:SF (match_dup 1) (match_dup 2)) + (const_int 0)))] "ALLOW_RX_FPU_INSNS" "fmul\t%2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "33,33,55") + [(set_attr "timings" "33,33,55") (set_attr "length" "3,7,5")] ) (define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=r,r,r") (minus:SF (match_operand:SF 1 "register_operand" "0,0,0") - (match_operand:SF 2 "rx_source_operand" "r,F,Q")))] + (match_operand:SF 2 "rx_source_operand" "r,F,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (minus:SF (match_dup 1) (match_dup 2)) + (const_int 0)))] "ALLOW_RX_FPU_INSNS" "fsub\t%Q2, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "44,44,66") + [(set_attr "timings" "44,44,66") (set_attr "length" "3,7,5")] ) (define_insn "fix_truncsfsi2" [(set (match_operand:SI 0 "register_operand" "=r,r") - (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))] + (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (fix:SI (match_dup 1)) + (const_int 0)))] "ALLOW_RX_FPU_INSNS" "ftoi\t%Q1, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "22,44") + [(set_attr "timings" "22,44") (set_attr "length" "3,5")] ) (define_insn "floatsisf2" [(set (match_operand:SF 0 "register_operand" "=r,r") - (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))] + (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q"))) + (set (reg:CC_ZS CC_REG) + (compare:CC_ZS (float:SF (match_dup 1)) + (const_int 0)))] "ALLOW_RX_FPU_INSNS" "itof\t%Q1, %0" - [(set_attr "cc" "set_zs") - (set_attr "timings" "22,44") + [(set_attr "timings" "22,44") (set_attr "length" "3,6")] ) @@ -1090,8 +1147,8 @@ ;; of three instructions at a time. (define_insn "bitset" - [(set:SI (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operand:SI 1 "register_operand" "0") + [(set:SI (match_operand:SI 0 "register_operand" "=r") + (ior:SI (match_operand:SI 1 "register_operand" "0") (ashift:SI (const_int 1) (match_operand:SI 2 "nonmemory_operand" "ri"))))] "" @@ -1100,8 +1157,8 @@ ) (define_insn "bitset_in_memory" - [(set:QI (match_operand:QI 0 "memory_operand" "=m") - (ior:QI (match_operand:QI 1 "memory_operand" "0") + [(set:QI (match_operand:QI 0 "memory_operand" "=m") + (ior:QI (match_operand:QI 1 "memory_operand" "0") (ashift:QI (const_int 1) (match_operand:QI 2 "nonmemory_operand" "ri"))))] "" @@ -1275,14 +1332,10 @@ ) (define_expand "insv" - [(set:SI (zero_extract:SI (match_operand:SI - 0 "nonimmediate_operand") ;; Destination - (match_operand - 1 "immediate_operand") ;; # of bits to set - (match_operand - 2 "immediate_operand")) ;; Starting bit - (match_operand - 3 "immediate_operand"))] ;; Bits to insert + [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination + (match_operand 1 "immediate_operand") ;; # of bits to set + (match_operand 2 "immediate_operand")) ;; Starting bit + (match_operand 3 "immediate_operand"))] ;; Bits to insert "" { if (rx_expand_insv (operands)) @@ -1337,8 +1390,7 @@ (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR) (clobber (reg:SI 1)) (clobber (reg:SI 2)) - (clobber (reg:SI 3)) - ] + (clobber (reg:SI 3))] "" "smovu" [(set_attr "length" "2") @@ -1352,11 +1404,11 @@ (clobber (reg:SI 1)) (clobber (reg:SI 2)) (clobber (reg:SI 3)) - ] + (clobber (reg:CC CC_REG)) + ] "" "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0" [(set_attr "length" "10") - (set_attr "cc" "clobber") (set_attr "timings" "1111")] ;; The timing is a guesstimate. ) @@ -1439,17 +1491,12 @@ ) (define_expand "cmpstrnsi" - [(set (match_operand:SI - 0 "register_operand") ;; Result - (unspec_volatile:SI [(match_operand:BLK - 1 "memory_operand") ;; String1 - (match_operand:BLK - 2 "memory_operand")] ;; String2 + [(set (match_operand:SI 0 "register_operand") ;; Result + (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1 + (match_operand:BLK 2 "memory_operand")] ;; String2 UNSPEC_CMPSTRN)) - (use (match_operand:SI - 3 "register_operand")) ;; Max Length - (match_operand:SI - 4 "immediate_operand")] ;; Known Align + (use (match_operand:SI 3 "register_operand")) ;; Max Length + (match_operand:SI 4 "immediate_operand")] ;; Known Align "" { rtx str1 = gen_rtx_REG (SImode, 1); @@ -1466,15 +1513,11 @@ ) (define_expand "cmpstrsi" - [(set (match_operand:SI - 0 "register_operand") ;; Result - (unspec_volatile:SI [(match_operand:BLK - 1 "memory_operand") ;; String1 - (match_operand:BLK - 2 "memory_operand")] ;; String2 + [(set (match_operand:SI 0 "register_operand") ;; Result + (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1 + (match_operand:BLK 2 "memory_operand")] ;; String2 UNSPEC_CMPSTRN)) - (match_operand:SI - 3 "immediate_operand")] ;; Known Align + (match_operand:SI 3 "immediate_operand")] ;; Known Align "" { rtx str1 = gen_rtx_REG (SImode, 1); @@ -1498,7 +1541,8 @@ (use (match_operand:BLK 2 "memory_operand" "m")) (clobber (reg:SI 1)) (clobber (reg:SI 2)) - (clobber (reg:SI 3))] + (clobber (reg:SI 3)) + (clobber (reg:CC CC_REG))] "" "scmpu ; Perform the string comparison mov #-1, %0 ; Set up -1 result (which cannot be created @@ -1639,11 +1683,11 @@ (define_insn "lrintsf2" [(set (match_operand:SI 0 "register_operand" "=r,r") (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")] - UNSPEC_BUILTIN_ROUND))] + UNSPEC_BUILTIN_ROUND)) + (clobber (reg:CC CC_REG))] "" "round\t%1, %0" - [(set_attr "cc" "clobber") - (set_attr "timings" "22,44") + [(set_attr "timings" "22,44") (set_attr "length" "3,5")] ) @@ -1663,22 +1707,20 @@ (define_insn "clrpsw" [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_BUILTIN_CLRPSW) - (clobber (cc0))] + (clobber (reg:CC CC_REG))] "" "clrpsw\t%F0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")] + [(set_attr "length" "2")] ) ;; Set Processor Status Word (define_insn "setpsw" [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_BUILTIN_SETPSW) - (clobber (cc0))] + (clobber (reg:CC CC_REG))] "" "setpsw\t%F0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")] + [(set_attr "length" "2")] ) ;; Move from control register diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 1d74d30c000..cbe28991c18 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -673,9 +673,6 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; /* We need current_function_outgoing_args to be valid. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Return doesn't modify the stack. */ -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0 - /* Register arguments. */ diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h index cde9c222546..98ca0a3537b 100644 --- a/gcc/config/score/score.h +++ b/gcc/config/score/score.h @@ -581,8 +581,6 @@ extern enum reg_class score_char_to_class[256]; `crtl->outgoing_args_size'. */ #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /* Passing Arguments in Registers */ /* Determine where to put an argument to a function. Value is zero to push the argument on the stack, diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 9482387ea56..ee3e05995d6 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -1423,17 +1423,6 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER]; /* Offset of first parameter from the argument pointer register value. */ #define FIRST_PARM_OFFSET(FNDECL) 0 -/* Value is the number of byte of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the SH, the caller does not pop any of its arguments that were passed - on the stack. */ -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Value is the number of bytes of arguments automatically popped when calling a subroutine. CUM is the accumulated argument list. diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 6c28e9838c8..6f6aec7d3f9 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1387,15 +1387,6 @@ extern char leaf_reg_remap[]; the function! */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - /* Define this macro if the target machine has "register windows". This C expression returns the register number as seen by the called function corresponding to register number OUT as seen by the calling function. diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index dc684ea8a13..4b7f9162395 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -432,8 +432,8 @@ static const struct attribute_spec spu_attribute_table[] = #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST spu_builtin_vectorization_cost -#undef TARGET_VECTOR_ALIGNMENT_REACHABLE -#define TARGET_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable +#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE +#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM #define TARGET_VECTORIZE_BUILTIN_VEC_PERM spu_builtin_vec_perm diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index 54b461235a7..d3880418c2f 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -334,8 +334,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) (0) - /* Register Arguments */ diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index cf6acf586c2..4ea89a218db 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -328,8 +328,6 @@ enum reg_class #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1) -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 - /* Function Arguments in Registers. */ diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index 4c4c270db71..25faff1e7dd 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -556,15 +556,6 @@ enum reg_class /* Keep the stack pointer constant throughout the function. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 - #define RETURN_ADDR_RTX(COUNT, FP) v850_return_addr (COUNT) /* Define a data type for recording info about an argument list diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 5d547fee8d5..b3dfcb1e079 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -58,6 +58,7 @@ static rtx vax_struct_value_rtx (tree, int); static rtx vax_builtin_setjmp_frame_value (void); static void vax_asm_trampoline_template (FILE *); static void vax_trampoline_init (rtx, tree, rtx); +static int vax_return_pops_args (tree, tree, int); /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -106,6 +107,8 @@ static void vax_trampoline_init (rtx, tree, rtx); #define TARGET_ASM_TRAMPOLINE_TEMPLATE vax_asm_trampoline_template #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT vax_trampoline_init +#undef TARGET_RETURN_POPS_ARGS +#define TARGET_RETURN_POPS_ARGS vax_return_pops_args struct gcc_target targetm = TARGET_INITIALIZER; @@ -2068,3 +2071,18 @@ vax_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) emit_insn (gen_sync_istream ()); } +/* Value is the number of bytes of arguments automatically + popped when returning from a subroutine call. + FUNDECL is the declaration node of the function (as a tree), + FUNTYPE is the data type of the function (as a tree), + or for a library call it is an identifier node for the subroutine name. + SIZE is the number of bytes of arguments passed on the stack. + + On the VAX, the RET insn pops a maximum of 255 args for any function. */ + +static int +vax_return_pops_args (tree fundecl ATTRIBUTE_UNUSED, + tree funtype ATTRIBUTE_UNUSED, int size) +{ + return size > 255 * 4 ? 0 : size; +} diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index e85ce01f820..88a8f1c9b1f 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -305,18 +305,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; /* Offset of first parameter from the argument pointer register value. */ #define FIRST_PARM_OFFSET(FNDECL) 4 -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNDECL is the declaration node of the function (as a tree), - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the VAX, the RET insn pops a maximum of 255 args for any function. */ - -#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ - ((SIZE) > 255 * 4 ? 0 : (SIZE)) - /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 80c296d930f..32819bc0de7 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -547,9 +547,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; 128-bit datatypes defined in TIE (e.g., for Vectra). */ #define STACK_BOUNDARY 128 -/* Functions do not pop arguments off the stack. */ -#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0 - /* Use a fixed register window size of 8. */ #define WINDOW_SIZE 8 |