This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Addressing Mode Woes
- To: GCC Mailing List <gcc at gcc dot gnu dot org>
- Subject: Addressing Mode Woes
- From: Soubhik Bhattacharya <soubhik at cse dot iitk dot ac dot in>
- Date: Wed, 6 Jun 2001 21:36:34 +0530 (IST)
- Organization: Dept of Computer Science IIT Kanpur
hi!
i'm trying my hand in porting GCC to a hypothetical target. the compiler
that i've built is aborting with the following message in a certain
scenario:
xgcc: Internal compiler error: program cc1 got fatal signal 6
there's surely something wrong in the machine description and i'll highly
appreciate if u can help me figure it out. now let me elaborate the
scenario (i'm sorry as i'm not able to describe it just in a few words):
following is the the c proggy i'm trying to compile (without any
optimization switch):
int not_main(void)
{
int i, j;
i=j;
}
both the variables have been allocated to stack. in .rtl dump i can see
the following insn, which moves data from one memory location to another:
(insn 8 6 10 (set (mem:DI (plus:DI (reg:DI 235)
(const_int -8)))
(mem:DI (plus:DI (reg:DI 235)
(const_int -16)))) -1 (nil)
(nil))
the kind of addr mode that has been used in the above insn (base plus
displacement) is supported by the target and so this is how my
GO_IF_LEGITIMATE_ADDRESS looks like:
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { \
if (RTX_OK_FOR_BASE_P (X)) \
goto ADDR; \
else if (RTX_OK_FOR_DISP_P (X)) \
goto ADDR; \
else if (GET_CODE (X) == PLUS) \
{ \
register rtx op0 = XEXP (X, 0); \
register rtx op1 = XEXP (X, 1); \
if (RTX_OK_FOR_BASE_P (op0)) \
{ \
if ( RTX_OK_FOR_INDEX_P (op1) || RTX_OK_FOR_DISP_P
(op1) ) \
goto ADDR; \
} \
else if (RTX_OK_FOR_BASE_P (op1)) \
{ \
if ( RTX_OK_FOR_INDEX_P (op0) || RTX_OK_FOR_DISP_P
(op0) ) \
goto ADDR; \
} \
} \
}
but to my surprise, i discovered after jump optimization pass that my gcc
is not using this addressing mode and instead opting for base register
addr mode. following is a sequence of insns from the .jump dump (%r6 is
the frame ptr reg, which is a valid base register):
(insn 15 6 16 (set (reg:DI 239)
(plus:DI (reg:DI 43 %r6)
(const_int -24))) -1 (nil)
(nil))
(insn 16 15 8 (set (reg:DI 241)
(plus:DI (reg:DI 43 %r6)
(const_int -32))) -1 (nil)
(nil))
(insn 8 16 10 (set (mem:DI (reg:DI 239))
(mem:DI (reg:DI 241))) 70 {tstdi-1} (nil)
(nil))
can u explain the following behavior?
the above problem is anyway, not a fatal one. but the next one is. in the
dump .lreg that appears after local register allocation, the above insns
become:
;; Insn is not within a basic block
(insn 15 6 16 (set (reg:DI 239)
(plus:DI (reg:DI 43 %r6)
(const_int -24))) 3 {addsf3+2} (nil)
(nil))
;; Insn is not within a basic block
(insn 16 15 8 (set (reg:DI 241)
(plus:DI (reg:DI 43 %r6)
(const_int -32))) 3 {addsf3+2} (nil)
(nil))
;; Insn is not within a basic block
(insn 8 16 10 (set (mem:DI (reg:DI 239))
(mem:DI (reg:DI 241))) 70 {tstdi-1} (nil)
(nil))
apparently the compiler breaks after this pass (.greg is empty:-)).
following are the relevant patterns from the .md file:
;; this is addsf3+2. constraint letter b allows regs %r8 thru %r15, which
;; are valid base regs. the letter L allows any integer between -4096 and
;; 4095.
(define_insn ""
[
(set (match_operand:DI 0 "register_operand"
"=h,a,b,c,h,a,b,c,h,a,b,c,h,a,b,c,h,a,b,c,h,a,b,c,h,a,b,c,h,a,b,c")
(plus:DI
(match_operand:DI 1 "register_operand"
"%h,h,h,h,a,a,a,a,b,b,b,b,c,c,c,c,h,h,h,h,a,a,a,a,b,b,b,b,c,c,c,c")
(match_operand:DI 2 "immediate_operand"
"M,M,M,M,M,M,M,M,M,M,M,M,M,M,M,M,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L") ) )
]
""
"@
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0
add %1, %2, %0"
)
;; this is tstdi-1. letter R stands for base addr mode. letter S stands
;; for base plus disp addr mode.
(define_insn ""
[
(set
(mem:DI (match_operand 0 "address_operand" "R,S,R,S"))
(mem:DI (match_operand 1 "address_operand" "R,R,S,S"))
)
]
""
"@
ldx [%1], %%r4\\n\\tstx %%r4, [%0]
ldx [%1], %%r4\\n\\tstx %%r4, [%0]
ldx [%1], %%r4\\n\\tstx %%r4, [%0]
ldx [%1], %%r4\\n\\tstx %%r4, [%0]"
)
let me know if u need more info. any insight into the trouble will be
really appreciated.
TIA.
regards,
soubhik.