Commit e6aecf8e by Bob Wilson Committed by Bob Wilson

xtensa.c (xtensa_copy_incoming_a7): Remove SUBREG on CQImode and CHImode…

xtensa.c (xtensa_copy_incoming_a7): Remove SUBREG on CQImode and CHImode incoming arguments in register a7.

	* config/xtensa/xtensa.c (xtensa_copy_incoming_a7): Remove SUBREG
	on CQImode and CHImode incoming arguments in register a7.
	(function_arg): Wrap BLKmode argument in register a7 in a PARALLEL.
	* config/xtensa/xtensa.h (BLOCK_REG_PADDING): Define.
	* config/xtensa/xtensa.md (movdi, movdf): Only call force_reg or
	xtensa_copy_incoming_a7 before reload.

From-SVN: r76742
parent 02307675
2004-01-27 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.c (xtensa_copy_incoming_a7): Remove SUBREG
on CQImode and CHImode incoming arguments in register a7.
(function_arg): Wrap BLKmode argument in register a7 in a PARALLEL.
* config/xtensa/xtensa.h (BLOCK_REG_PADDING): Define.
* config/xtensa/xtensa.md (movdi, movdf): Only call force_reg or
xtensa_copy_incoming_a7 before reload.
2004-01-27 J"orn Rennecke <joern.rennecke@superh.com>
* coverage.c (get_coverage_counts): Give a different message
......
......@@ -1327,7 +1327,27 @@ xtensa_copy_incoming_a7 (rtx *operands, enum machine_mode mode)
if (a7_overlap_mentioned_p (operands[1])
&& !cfun->machine->incoming_a7_copied)
{
rtx mov;
rtx mov, src;
/* Despite defining SPLIT_COMPLEX_ARGS, complex function
arguments may still appear if they are wrapped in a struct.
For CQImode and CHImode arguments, this results in a move
with a source operand of the form: "(subreg:SI (reg:CHI a7)
0)". The subreg is later removed by the reload pass,
resulting in the RTL for a7 being regenerated using
hard_frame_pointer_rtx, and making it impossible for us to
distinguish the function argument. Detect this here when
generating the RTL and remove the subreg immediately so that
reload won't mess it up. */
src = operands[1];
if (GET_CODE (src) == SUBREG
&& GET_CODE (SUBREG_REG (src)) == REG
&& REGNO (SUBREG_REG (src)) == A7_REG
&& SUBREG_BYTE (src) == 0
&& (GET_MODE (SUBREG_REG (src)) == CHImode
|| GET_MODE (SUBREG_REG (src)) == CQImode))
operands[1] = gen_raw_REG (mode, A7_REG);
switch (mode)
{
case DFmode:
......@@ -1773,11 +1793,15 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
rtx that is not equal to hard_frame_pointer_rtx. For multi-word
modes for which we don't define move patterns, we can't control
the expansion unless we explicitly list the individual registers
in a PARALLEL. */
if (mode != DImode && mode != DFmode
&& regno < A7_REG
&& regno + words > A7_REG)
in a PARALLEL. Likewise, a single-word BLKmode argument passed
in a7 must be wrapped in a PARALLEL to avoid code that takes the
register number and builds a new REG. This is extremely fragile
but seems to be the best solution for now. */
if ((mode != DImode && mode != DFmode
&& regno < A7_REG
&& regno + words > A7_REG)
|| (mode == BLKmode && regno == A7_REG))
{
rtx result;
int n;
......
......@@ -799,6 +799,12 @@ typedef struct xtensa_args {
/* Pass complex arguments independently. */
#define SPLIT_COMPLEX_ARGS 1
/* Because Xtensa's function_arg() wraps BLKmode arguments passed in
a7 inside a PARALLEL, BLOCK_REG_PADDING needs to be defined
to get emit_group_store to do the right thing. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
FUNCTION_ARG_PADDING (MODE, TYPE)
/* Profiling Xtensa code is typically done with the built-in profiling
feature of Tensilica's instruction set simulator, which does not
require any compiler support. Profiling code on a real (i.e.,
......
;; GCC machine description for Tensilica's Xtensa architecture.
;; Copyright (C) 2001 Free Software Foundation, Inc.
;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
;; This file is part of GCC.
......@@ -803,12 +803,15 @@
if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
operands[1] = force_const_mem (DImode, operands[1]);
if (!register_operand (operands[0], DImode)
&& !register_operand (operands[1], DImode))
operands[1] = force_reg (DImode, operands[1]);
if (!(reload_in_progress | reload_completed))
{
if (!register_operand (operands[0], DImode)
&& !register_operand (operands[1], DImode))
operands[1] = force_reg (DImode, operands[1]);
if (xtensa_copy_incoming_a7 (operands, DImode))
DONE;
if (xtensa_copy_incoming_a7 (operands, DImode))
DONE;
}
})
(define_insn_and_split "movdi_internal"
......@@ -1012,12 +1015,15 @@
if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
operands[1] = force_const_mem (DFmode, operands[1]);
if (!register_operand (operands[0], DFmode)
&& !register_operand (operands[1], DFmode))
operands[1] = force_reg (DFmode, operands[1]);
if (!(reload_in_progress | reload_completed))
{
if (!register_operand (operands[0], DFmode)
&& !register_operand (operands[1], DFmode))
operands[1] = force_reg (DFmode, operands[1]);
if (xtensa_copy_incoming_a7 (operands, DFmode))
DONE;
if (xtensa_copy_incoming_a7 (operands, DFmode))
DONE;
}
})
(define_insn_and_split "movdf_internal"
......
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