This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]