This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: Global Reload Problem
- From: Gyle Yearsley <gyearsley at zilog dot com>
- To: 'James E Wilson' <wilson at specifixinc dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 3 Feb 2005 10:22:44 -0800
- Subject: RE: Global Reload Problem
James,
Thanks a lot you were correct. I did have the strict version but it wasn't
getting called because the macros were in the .c file.
I have one other problem which I cannot find a solution for. Consider the
insn.
(insn 118 117 119 2 0x400193c8 (set (reg:HI 87)
(ashift:HI (subreg:HI (reg:QI 84) 0)
(const_int 8 [0x8]))) 35 {ashlhi3} (insn_list 116 (nil))
(expr_list:REG_DEAD (reg:QI 84)
(nil)))
Operand one is where the problem occurs. In push_reload (in reload.c) the
function find_valid_class (also in reload.c) is being called with operand 1
above.
in_class
= find_valid_class (inmode,
subreg_regno_offset (REGNO (SUBREG_REG (in)),
GET_MODE (SUBREG_REG
(in)),
SUBREG_BYTE (in),
GET_MODE (in)),
REGNO (SUBREG_REG (in)));
Embedded in the call is a call to subreg_regno_offset (in reload.c). This
function returns the offset value based upon the mode of (in) and the mode
of the subreg(in). Since (in) has a HI mode and subreg(in) has mode QI and
BYTES_BIG_ENDIAN = 1, subreg_regno_offset returns a -1 offset. Which based
upon the documentation is correct. However when this negative value gets
passed to find_valid_class it creates a seg fault in the code below.
for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
&& TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
&& ! HARD_REGNO_MODE_OK (regno + n, m1))
I believe the seg fault is happening in the second TEST_HARD_REG_BIT since
the regno(0)+n(-1) for regno = 0 is -1. The HARD_REGNO_MODE_OK is a c
function and not a macro. When stepping it never reaches this function, so I
do not believe it is happening in this function. I also placed an abort if
regno was negative in the HARD_REGNO_MODE_OK function and it still seg
faulted. This processor has 33 registers defined so reg_class_contents is a
array of two HOST_WIDE_INTEGERS. I have looked a TEST_HARD_REG_BIT and do
not see why it would seg fault since it looks like it is a simple shift
function. If I change the starting value of regno to the absolute value of n
if n is negative, the code no longer seg faults and finishes compiling.
Any help would be appreciated.
Thanks again,
Gyle
-----Original Message-----
From: James E Wilson [mailto:wilson@specifixinc.com]
Sent: Tuesday, February 01, 2005 4:13 PM
To: Gyle Yearsley
Cc: gcc@gcc.gnu.org
Subject: Re: Global Reload Problem
Gyle Yearsley wrote:
> (mem/s:QI (plus:SI (mem:SI (plus:SI (reg/f:SI 31 q60)
> (const_int -10))
This is usually a REG_OK_STRICT bug in your port.
A pseudo-reg is assumed to be a equivalent to a hard register before
reload, but during reload an unallocated pseudo-reg is always a stack
slot. Thus, macros in your backend must be careful to handle pseudo
regs correctly depending on whether we are inside reload or not. This
is controlled via REG_OK_STRICT.
Usually this bug happens when you move macro definitions from the .h
file into functions in the .c file, and fail to pass REG_OK_STRICT as a
parameter to the function and check it in the function. For an example
of how to do this correctly, see the mips port, and the definitions of
REG_MODE_OK_FOR_BASE_P in the mips.h port.
This could also happen if you aren't using standard macros/functions to
check whether pseudo-regs are valid operands.
--
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com