This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: unexpected RTL
- From: Florent DEFAY <spira dot inhabitant at gmail dot com>
- To: gcc-help at gcc dot gnu dot org
- Date: Fri, 27 Mar 2009 17:37:03 +0100
- Subject: Re: unexpected RTL
>> According to the error message, the RTL contains memory addressed by
>> memory. It is not possible according to my
>> GO_IF_LEGITIMATE_ADDRESS, whatever the mode strict or not.
>
> This kind of memory address is generated during the reload pass. Reload
> should clean it up. The question is why it didn't. I don't see
> anything wrong with your code, but you didn't show us
> CONSTANT_ADDRESS_P.
Thank you for your reply.
At the end of the email I include the pieces of implementation at present day.
I still have the same problem, but I now come with clues.
Here is a smart example:
________ex.c_________________________________
float
function1 ()
{
int m = 1;
return m < 0 ? 1 : 8;
}
_____________________________________________
_______target-complilation_______________________
$ target-gcc -S w.c
w.c: In function ‘function1’:
w.c:7: error: insn does not satisfy its constraints:
(insn 22 46 26 w.c:6 (set (mem/c/i:HI (plus:HI (mem/f/c/i:HI (plus:HI
(reg/f:HI 5 r5)
(const_int 2 [0x2])) [0 D.1178+0 S2 A16])
(const_int 2 [0x2])) [0 <result>+2 S2 A16])
(reg:HI 0 r0)) 5 {movhi} (nil))
w.c:7: internal compiler error: in final_scan_insn, at final.c:2548
_____________________________________________
______resulting_output_assembler________________
cmp.w r1,-4(r5)
jge #.L2
move.w #16256,r0
move.w r0,-8(r5)
move.w #0,r1
move.w r1,-6(r5)
ja #.L3
.L2:
move.w #16640,r0
move.w r0,-8(r5)
move.w #0,r1
move.w r1,-6(r5)
.L3:
move.w -8(r5),r0
move.w 2(r5),r1
move.w r0,(r1)
move.w -6(r5),r0
_____________________________________________
As it crashed while compilation, asm is not complete. The lines I
expect to complete this are:
move.w r0,2(r1)
ret
Base + displacement addressing mode should be ok with any register. It
seems like GCC refuses to generate "2(r1)" as if r1 does not support
base+displacement. Note that r5 is FP.
If you need more source, please tell me.
Thank you very much.
Regards.
Florent
________________movhi_pattern______________________
(define_insn "movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,m,r,r")
(match_operand:HI 1 "general_operand" "r,r,m,i")
)]
""
"@
move.w\t%1,%0
move.w\t%1,%0
move.w\t%1,%0
move.w\t%1,%0"
)
________________________________________________
_______________target.c__[cuts]____________________
enum reg_class
target_regno_reg_class (int r)
{
switch (r)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
return BASE_REGS;
break;
case 6:
return SP_REG;
break;
case 7:
return PC_REG;
break;
default:
return NO_REGS;
break;
}
}
int
target_regno_ok_for_base_p (int r)
{
if (r < FIRST_PSEUDO_REGISTER && r >= 0)
return 1;
if (reg_renumber
&& reg_renumber[r] < FIRST_PSEUDO_REGISTER
&& reg_renumber[r] >= 0)
return 1;
return 0;
}
int
target_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
rtx x, int strict)
{
rtx op1,op2;
if (CONSTANT_ADDRESS_P (x))
return 1;
if (GET_CODE(x) == REG
&& REG_OK_FOR_BASE_P (x))
return 1;
if (GET_CODE(x) == PLUS)
{
op1 = XEXP (x,0);
op2 = XEXP (x,1);
if (GET_CODE (op1) == REG
&& REG_OK_FOR_BASE_P (op1)
&& CONSTANT_P (op2)
&& INTVAL (op2) >= -32768
&& INTVAL (op2) < 32768)
return 1;
}
return 0;
}
_______________________________________________
_________________target.h__[cuts]_________________
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
"PC_REG", \
"SP_REG", \
"GENERAL_REGS", \
"BASE_REGS", \
"ALL_REGS" \
}
#define REG_CLASS_CONTENTS \
{ \
{0x00000000ul}, /* NO_REGS */ \
{0x00000080ul}, /* PC_REG */ \
{0x00000040ul}, /* SP_REG */ \
{0x0000007ful}, /* GENERAL_REGS */ \
{0x0000007ful}, /* BASE_REGS */ \
{0x0000007ful} /* ALL_REGS */ \
}
#define REGNO_REG_CLASS(R) target_regno_reg_class(R)
#define BASE_REG_CLASS BASE_REGS
#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
#define INDEX_REG_CLASS NO_REGS
#define REGNO_OK_FOR_BASE_P(R) target_regno_ok_for_base_p(R)
#define MAX_REGS_PER_ADDRESS 1
#ifdef REG_OK_STRICT
# define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR) \
{ \
if (target_legitimate_address_p (mode, operand, 1)) \
goto ADDR; \
}
# else
# define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR) \
{ \
if (target_legitimate_address_p (mode, operand, 0)) \
goto ADDR; \
}
#endif
#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
#define REG_OK_FOR_BASE_NOSTRICT_P(X) \
(REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
#ifdef REG_OK_STRICT
# define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X)
#else
# define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NOSTRICT_P (X)
#endif
_______________________________________________________________________