Commit e41b2a33 by Peter Bergner Committed by Peter Bergner

re PR target/34814 (SDmode function args not passed according to ABI specification)

	PR target/34814
	* doc/tm.texi (TARGET_EXPAND_TO_RTL_HOOK): Document.
	(TARGET_INSTANTIATE_DECLS): Likewise.
	* target.h (expand_to_rtl_hook): New target hook.
	(instantiate_decls): Likewise.
	* function.c (instantiate_decl): Make non-static.  Rename to...
	(instantiate_decl_rtl): ... this.
	(instantiate_expr): Use instantiate_decl_rtl.
	(instantiate_decls_1): Likewise.
	(instantiate_decls): Likewise.
	(instantiate_virtual_regs: Call new instantiate_decls taget hook.
	* function.h (instantiate_decl_rtl): Add prototype.
	* cfgexpand.c (target.h): New include.
	(tree_expand_cfg): Call new expand_to_rtl_hook target hook.
	* target-def.h (TARGET_EXPAND_TO_RTL_HOOK): New define.
	(TARGET_INSTANTIATE_DECLS): Likewise.
	(TARGET_INITIALIZER): New target hooks added.
	* config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_rtx):
	New prototype.
	* config/rs6000/rs6000.c (tree-flow.h): New include.
	(machine_function): Add sdmode_stack_slot field.
	(rs6000_alloc_sdmode_stack_slot): New function.
	(rs6000_instantiate_decls): Likewise.
	(rs6000_secondary_memory_needed_rtx): Likewise.
	(rs6000_check_sdmode): Likewise.
	(TARGET_EXPAND_TO_RTL_HOOK): Target macro defined.
	(TARGET_INSTANTIATE_DECLS): Likewise.
	(rs6000_hard_regno_mode_ok): Allow SDmode.
	(num_insns_constant): Likewise.  Handle _Decimal32 constants.
	(rs6000_emit_move): Handle SDmode.
	(function_arg_advance): Likewise.
	(function_arg): Likewise.
	(rs6000_gimplify_va_arg): Likewise.  Add special handling of
	SDmode var args for 32-bit compiles.
	(rs6000_secondary_reload_class): Handle SDmode.
	(rs6000_output_function_epilogue): Likewise.
	(rs6000_function_value): Simplify if statement.
	(rs6000_libcall_value): Likewise.
	* config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Handle SDmode.
	(SECONDARY_MEMORY_NEEDED_RTX): Add define.
	* config/rs6000/dfp.md (movsd): New define_expand and splitter.
	(movsd_hardfloat): New define_insn.
	(movsd_softfloat): Likewise.
	(movsd_store): Likewise.
	(movsd_load): Likewise.
	(extendsddd2): Likewise.
	(extendsdtd2): Likewise.
	(truncddsd2): Likewise.
	(movdd_hardfloat64): Fixup comment.
	(UNSPEC_MOVSD_LOAD): New constant.
	(UNSPEC_MOVSD_STORE): Likewise.

Co-Authored-By: Janis Johnson <janis187@us.ibm.com>

From-SVN: r131869
parent 6f536f74
2007-01-26 Peter Bergner <bergner@vnet.ibm.com>
Janis Johnson <janis187@us.ibm.com>
PR target/34814
* doc/tm.texi (TARGET_EXPAND_TO_RTL_HOOK): Document.
(TARGET_INSTANTIATE_DECLS): Likewise.
* target.h (expand_to_rtl_hook): New target hook.
(instantiate_decls): Likewise.
* function.c (instantiate_decl): Make non-static. Rename to...
(instantiate_decl_rtl): ... this.
(instantiate_expr): Use instantiate_decl_rtl.
(instantiate_decls_1): Likewise.
(instantiate_decls): Likewise.
(instantiate_virtual_regs: Call new instantiate_decls taget hook.
* function.h (instantiate_decl_rtl): Add prototype.
* cfgexpand.c (target.h): New include.
(tree_expand_cfg): Call new expand_to_rtl_hook target hook.
* target-def.h (TARGET_EXPAND_TO_RTL_HOOK): New define.
(TARGET_INSTANTIATE_DECLS): Likewise.
(TARGET_INITIALIZER): New target hooks added.
* config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_rtx):
New prototype.
* config/rs6000/rs6000.c (tree-flow.h): New include.
(machine_function): Add sdmode_stack_slot field.
(rs6000_alloc_sdmode_stack_slot): New function.
(rs6000_instantiate_decls): Likewise.
(rs6000_secondary_memory_needed_rtx): Likewise.
(rs6000_check_sdmode): Likewise.
(TARGET_EXPAND_TO_RTL_HOOK): Target macro defined.
(TARGET_INSTANTIATE_DECLS): Likewise.
(rs6000_hard_regno_mode_ok): Allow SDmode.
(num_insns_constant): Likewise. Handle _Decimal32 constants.
(rs6000_emit_move): Handle SDmode.
(function_arg_advance): Likewise.
(function_arg): Likewise.
(rs6000_gimplify_va_arg): Likewise. Add special handling of
SDmode var args for 32-bit compiles.
(rs6000_secondary_reload_class): Handle SDmode.
(rs6000_output_function_epilogue): Likewise.
(rs6000_function_value): Simplify if statement.
(rs6000_libcall_value): Likewise.
* config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Handle SDmode.
(SECONDARY_MEMORY_NEEDED_RTX): Add define.
* config/rs6000/dfp.md (movsd): New define_expand and splitter.
(movsd_hardfloat): New define_insn.
(movsd_softfloat): Likewise.
(movsd_store): Likewise.
(movsd_load): Likewise.
(extendsddd2): Likewise.
(extendsdtd2): Likewise.
(truncddsd2): Likewise.
(movdd_hardfloat64): Fixup comment.
(UNSPEC_MOVSD_LOAD): New constant.
(UNSPEC_MOVSD_STORE): Likewise.
2008-01-26 Jakub Jelinek <jakub@redhat.com>
PR c++/34965
......
......@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "tree-inline.h"
#include "value-prof.h"
#include "target.h"
/* Verify that there is exactly single jump instruction since last and attach
REG_BR_PROB note specifying probability.
......@@ -1873,6 +1874,8 @@ tree_expand_cfg (void)
/* Mark arrays indexed with non-constant indices with TREE_ADDRESSABLE. */
discover_nonconstant_array_refs ();
targetm.expand_to_rtl_hook ();
/* Expand the variables recorded during gimple lowering. */
expand_used_vars ();
......
......@@ -20,6 +20,138 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;;
;; UNSPEC usage
;;
(define_constants
[(UNSPEC_MOVSD_LOAD 400)
(UNSPEC_MOVSD_STORE 401)
])
(define_expand "movsd"
[(set (match_operand:SD 0 "nonimmediate_operand" "")
(match_operand:SD 1 "any_operand" ""))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
"{ rs6000_emit_move (operands[0], operands[1], SDmode); DONE; }")
(define_split
[(set (match_operand:SD 0 "gpc_reg_operand" "")
(match_operand:SD 1 "const_double_operand" ""))]
"reload_completed
&& ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
|| (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG
&& REGNO (SUBREG_REG (operands[0])) <= 31))"
[(set (match_dup 2) (match_dup 3))]
"
{
long l;
REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
if (! TARGET_POWERPC64)
operands[2] = operand_subword (operands[0], 0, 0, SDmode);
else
operands[2] = gen_lowpart (SImode, operands[0]);
operands[3] = gen_int_mode (l, SImode);
}")
(define_insn "movsd_hardfloat"
[(set (match_operand:SD 0 "nonimmediate_operand" "=r,r,m,f,*c*l,*q,!r,*h,!r,!r")
(match_operand:SD 1 "input_operand" "r,m,r,f,r,r,h,0,G,Fn"))]
"(gpc_reg_operand (operands[0], SDmode)
|| gpc_reg_operand (operands[1], SDmode))
&& (TARGET_HARD_FLOAT && TARGET_FPRS)"
"@
mr %0,%1
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0
fmr %0,%1
mt%0 %1
mt%0 %1
mf%1 %0
{cror 0,0,0|nop}
#
#"
[(set_attr "type" "*,load,store,fp,mtjmpr,*,mfjmpr,*,*,*")
(set_attr "length" "4,4,4,4,4,4,4,4,4,8")])
(define_insn "movsd_softfloat"
[(set (match_operand:SD 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
(match_operand:SD 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
"(gpc_reg_operand (operands[0], SDmode)
|| gpc_reg_operand (operands[1], SDmode))
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
"@
mr %0,%1
mt%0 %1
mt%0 %1
mf%1 %0
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1
{liu|lis} %0,%v1
{cal|la} %0,%a1
#
#
{cror 0,0,0|nop}"
[(set_attr "type" "*,mtjmpr,*,mfjmpr,load,store,*,*,*,*,*,*")
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
(define_insn "movsd_store"
[(set (match_operand:DD 0 "nonimmediate_operand" "=m")
(unspec:DD [(match_operand:SD 1 "input_operand" "f")]
UNSPEC_MOVSD_STORE))]
"(gpc_reg_operand (operands[0], DDmode)
|| gpc_reg_operand (operands[1], SDmode))
&& TARGET_HARD_FLOAT && TARGET_FPRS"
"stfd%U0%X0 %1,%0"
[(set_attr "type" "fpstore")
(set_attr "length" "4")])
(define_insn "movsd_load"
[(set (match_operand:SD 0 "nonimmediate_operand" "=f")
(unspec:SD [(match_operand:DD 1 "input_operand" "m")]
UNSPEC_MOVSD_LOAD))]
"(gpc_reg_operand (operands[0], SDmode)
|| gpc_reg_operand (operands[1], DDmode))
&& TARGET_HARD_FLOAT && TARGET_FPRS"
"lfd%U1%X1 %0,%1"
[(set_attr "type" "fpload")
(set_attr "length" "4")])
;; Hardware support for decimal floating point operations.
(define_insn "extendsddd2"
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
(float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
"TARGET_DFP"
"dctdp %0,%1"
[(set_attr "type" "fp")])
(define_expand "extendsdtd2"
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
(float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "f")))]
"TARGET_DFP"
{
rtx tmp = gen_reg_rtx (DDmode);
emit_insn (gen_extendsddd2 (tmp, operands[1]));
emit_insn (gen_extendddtd2 (operands[0], tmp));
DONE;
})
(define_insn "truncddsd2"
[(set (match_operand:SD 0 "gpc_reg_operand" "=f")
(float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "f")))]
"TARGET_DFP"
"drsp %0,%1"
[(set_attr "type" "fp")])
(define_expand "negdd2"
[(set (match_operand:DD 0 "gpc_reg_operand" "")
(neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
......@@ -309,7 +441,7 @@
(set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
; ld/std require word-aligned displacements -> 'Y' constraint.
; List Y->r and r->Y before r->r for reload.(define_insn "*movdd_hardfloat64"
; List Y->r and r->Y before r->r for reload.
(define_insn "*movdd_hardfloat64"
[(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
(match_operand:DD 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
......
......@@ -103,6 +103,7 @@ extern void rs6000_fatal_bad_address (rtx);
extern rtx create_TOC_reference (rtx);
extern void rs6000_split_multireg_move (rtx, rtx);
extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
extern rtx rs6000_secondary_memory_needed_rtx (enum machine_mode);
extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
int, int, int, int *);
......
......@@ -622,7 +622,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
|| (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == DImode) \
&& (ALIGN) < 32))
......@@ -1173,6 +1173,13 @@ enum reg_class
|| (CLASS1) == ALTIVEC_REGS \
|| (CLASS2) == ALTIVEC_REGS))
/* For cpus that cannot load/store SDmode values from the 64-bit
FP registers without using a full 64-bit load/store, we need
to allocate a full 64-bit stack slot for them. */
#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
rs6000_secondary_memory_needed_rtx (MODE)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
......
......@@ -1502,6 +1502,20 @@ Returns true if the target supports decimal floating point.
Returns true if the target supports fixed-point arithmetic.
@end deftypefn
@deftypefn {Target Hook} void TARGET_EXPAND_TO_RTL_HOOK (void)
This hook is called just before expansion into rtl, allowing the target
to perform additional initializations or analysis before the expansion.
For example, the rs6000 port uses it to allocate a scratch stack slot
for use in copying SDmode values between memory and floating point
registers whenever the function being expanded has any SDmode
usage.
@end deftypefn
@deftypefn {Target Hook} void TARGET_INSTANTIATE_DECLS (void)
This hook allows the backend to perform additional instantiations on rtl
that are not actually in any insns yet, but will be later.
@end deftypefn
@deftypefn {Target Hook} {const char *} TARGET_MANGLE_TYPE (tree @var{type})
If your target defines any fundamental types, or any types your target
uses should be mangled differently from the default, define this hook
......
......@@ -1568,8 +1568,8 @@ instantiate_virtual_regs_in_insn (rtx insn)
/* Subroutine of instantiate_decls. Given RTL representing a decl,
do any instantiation required. */
static void
instantiate_decl (rtx x)
void
instantiate_decl_rtl (rtx x)
{
rtx addr;
......@@ -1579,8 +1579,8 @@ instantiate_decl (rtx x)
/* If this is a CONCAT, recurse for the pieces. */
if (GET_CODE (x) == CONCAT)
{
instantiate_decl (XEXP (x, 0));
instantiate_decl (XEXP (x, 1));
instantiate_decl_rtl (XEXP (x, 0));
instantiate_decl_rtl (XEXP (x, 1));
return;
}
......@@ -1610,7 +1610,7 @@ instantiate_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
*walk_subtrees = 0;
if (DECL_P (t) && DECL_RTL_SET_P (t))
instantiate_decl (DECL_RTL (t));
instantiate_decl_rtl (DECL_RTL (t));
}
return NULL;
}
......@@ -1626,7 +1626,7 @@ instantiate_decls_1 (tree let)
for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
{
if (DECL_RTL_SET_P (t))
instantiate_decl (DECL_RTL (t));
instantiate_decl_rtl (DECL_RTL (t));
if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
{
tree v = DECL_VALUE_EXPR (t);
......@@ -1650,8 +1650,8 @@ instantiate_decls (tree fndecl)
/* Process all parameters of the function. */
for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
{
instantiate_decl (DECL_RTL (decl));
instantiate_decl (DECL_INCOMING_RTL (decl));
instantiate_decl_rtl (DECL_RTL (decl));
instantiate_decl_rtl (DECL_INCOMING_RTL (decl));
if (DECL_HAS_VALUE_EXPR_P (decl))
{
tree v = DECL_VALUE_EXPR (decl);
......@@ -1715,6 +1715,8 @@ instantiate_virtual_regs (void)
/* Instantiate the virtual registers in the DECLs for debugging purposes. */
instantiate_decls (current_function_decl);
targetm.instantiate_decls ();
/* Indicate that, from now on, assign_stack_local should use
frame_pointer_rtx. */
virtuals_instantiated = 1;
......
......@@ -491,6 +491,7 @@ extern int trampolines_created;
extern void set_cfun (struct function *new_cfun);
extern void push_cfun (struct function *new_cfun);
extern void pop_cfun (void);
extern void instantiate_decl_rtl (rtx x);
/* For backward compatibility... eventually these should all go away. */
#define current_function_pops_args (cfun->pops_args)
......
......@@ -604,6 +604,14 @@
#define TARGET_SECONDARY_RELOAD default_secondary_reload
#endif
#ifndef TARGET_EXPAND_TO_RTL_HOOK
#define TARGET_EXPAND_TO_RTL_HOOK hook_void_void
#endif
#ifndef TARGET_INSTANTIATE_DECLS
#define TARGET_INSTANTIATE_DECLS hook_void_void
#endif
/* C specific. */
#ifndef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix
......@@ -771,6 +779,8 @@
TARGET_INVALID_UNARY_OP, \
TARGET_INVALID_BINARY_OP, \
TARGET_SECONDARY_RELOAD, \
TARGET_EXPAND_TO_RTL_HOOK, \
TARGET_INSTANTIATE_DECLS, \
TARGET_C, \
TARGET_CXX, \
TARGET_EXTRA_LIVE_ON_ENTRY, \
......
......@@ -849,6 +849,15 @@ struct gcc_target
enum machine_mode,
struct secondary_reload_info *);
/* This target hook allows the backend to perform additional
processing while initializing for variable expansion. */
void (* expand_to_rtl_hook) (void);
/* This target hook allows the backend to perform additional
instantiations on rtx that are not actually in insns yet,
but will be later. */
void (* instantiate_decls) (void);
/* Functions specific to the C family of frontends. */
struct c {
/* Return machine mode for non-standard suffix
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment