This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Bug in cse? (Or in LABEL_PRESERVE_P?)
- To: gcc <gcc at gcc dot gnu dot org>
- Subject: Bug in cse? (Or in LABEL_PRESERVE_P?)
- From: Adrian von Bidder <avbidder at acter dot ch>
- Date: Tue, 13 Nov 2001 15:25:12 +0100
Heyho!
For my embedded-pic for ARM gcc-3.0 project, I do the addressing of code
pc relative. For this I generate additional labels in the code.
Asm output looks like this:
...
ldr r3, .L20
.L10:
add r3, pc, r3
...
.L20: .word some_function-(.L10+8)
(in the code I have right now r3 is then stored in a function pointer.
But this is irrelevant here).
My problem is that when optimizing, labels such as .L10 are sometimes
eliminated from the code, but are still referenced. Thus, the assembler
will complain. An example:
...
ldr r3, .L20
.L10:
add r3, pc, r3
b .L15
...
ldr r3, .L20+4
.L11:
add r3, pc, r3
b .L15
...
ldr r3, .L20+8
.L12:
add r3, pc, r3
...
.L15:
...
.L20:
.word some_function-(.L10+8)
.word some_other_fn-(.L11+8)
.word yet_another_fn-(.L12+8)
will be optimized to
...
ldr r3, .L20
b .L15
...
ldr r3, .L20+4
b .L15
...
ldr r3, .L20+8
...
.L15
.L12
add r3, pc, r3
...
.L20:
.word some_function-(.L10+8)
.word some_other_fn-(.L11+8)
.word yet_another_fn-(.L12+8)
leaving .L10 and .L11 undefined. the assembler complains
===
jccoefct.s:113: Error: Subtraction of two symbols in different sections
".text" {.text section} - ".L10" {*UND* section} at file address 328.
===
for every such label. The code I use to generate these labels looks like
this: (it's in arm.c:legitimize_pic_address, it was taken streight out
of Vladim Lebedev's arm-uclinux [-mdisable-got] patch):
===
/* this is a symbol in the .text segment */
rtx insn;
rtx addr = gen_reg_rtx (Pmode);
rtx l1 = gen_label_rtx ();
rtx tmp = plus_constant(gen_rtx_LABEL_REF(Pmode, l1),
TARGET_ARM ? 8 : 4);
pic_ref = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig,
tmp));
LABEL_PRESERVE_P (l1) = 1;
if (TARGET_ARM)
insn = gen_pic_load_addr_arm (addr, pic_ref);
else
insn = gen_pic_load_addr_thumb (addr, pic_ref);
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, l1,
REG_NOTES (insn));
emit_insn (insn);
if (TARGET_ARM)
emit_insn (insn = gen_pic_add_dot_plus_eight (addr, l1));
else
emit_insn (insn = gen_pic_add_dot_plus_four (addr, l1));
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig,
REG_NOTES (insn));
RTX_UNCHANGING_P (pic_ref) = 1;
return addr;
===
(of course this is within a 'if (<reference to be generated is in the
.text segment>)' block)
I suspect that the problem is not wholly mine - I have seen errors about
undefined internal labels on the older compiler we use, but I can't
reproduce them right now.
Anyway - I hope somebody sees what the problem is and has an idea on how
to fix it.
(linked to this: How do I properly decide if a label_ref or symbol_ref
is in the .text segment? I guess this would be in ENCODE_SECTION_INFO.)
greets from Zürich
-- vbi