This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: PIC on m68k - the saga continues
- From: Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- To: gcc at gcc dot gnu dot org
- Date: Tue, 10 Dec 2002 17:11:11 -0500
- Subject: Re: PIC on m68k - the saga continues
I'm in the midst of forcing a mind-meld by extracting the PIC handling
from i386 and pushing it into m68k so I can support PIC handling on
ColdFire which can't deal with 32-bit offset addressing mode (mode-6
variant).
I fixed my previous problem of messing up the definition of
GO_IF_LEGITIMATE_ADDRESS.
One thing that I noticed is in the new legitimize_pic_address:
else if (GET_CODE (addr) == SYMBOL_REF)
{
/* This symbol must be referenced via a load from the
Global Offset Table (@GOT). */
current_function_uses_pic_offset_table = 1;
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 6);
new = gen_rtx_CONST (Pmode, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
new = gen_rtx_MEM (Pmode, new);
RTX_UNCHANGING_P (new) = 1;
set_mem_alias_set (new, m68k_GOT_alias_set ());
if (reg == 0)
reg = gen_reg_rtx (Pmode);
emit_move_insn (reg, new);
new = reg;
}
This generates a single instruction to handle the PIC, but in the case
of ColdFire I need to split this into two instructions, one to load
the value of the symbol address(with @GOT relocation) into the temp
register, and the other to actually load the temp with %a5 + the value
that was in temp.
1) Is this the place to do that?
I'm just trying to bootstrap the compiler with the current mind-meld,
and its blowing up building PIC on crtstuff.c:
[pbarada: ~/work/cvs-wavemark/cross-linux-tools/foo/m68k-linux-bootstrap/gcc] > ./xgcc -B./ -B/home/mylocal/xcomp/target/m68k-linux/bin/ -isystem /home/mylocal/xcomp/target/m68k-linux/include -isystem /home/mylocal/xcomp/target/m68k-linux/sys-include -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -isystem ./include -I. -I. -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/. -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/config -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/../include -g0 -finhibit-size-directive -fno-inline-functions -fno-exceptions -fPIC -Dinhibit_libc -c /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c -DCRT_BEGIN -DCRTSTUFFS_O -o crtbeginS.o
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c: In function `__do_global_dtors_aux':
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c:286: unrecognizable insn:
(insn 34 32 35 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
(mem/f:SI (reg/f:SI 35) [6 __dso_handle+0 S4 A16])) -1 (insn_list 32 (nil))
(expr_list:REG_DEAD (reg/f:SI 35)
(nil)))
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c:286: Internal compiler error in extract_insn, at recog.c:2148
>From the dump of crtstuff.c.17.ce I see:
(insn 32 31 34 (set (reg/f:SI 35)
(mem/u:SI (plus:SI (reg:SI 13 %a5)
(const:SI (unspec:SI[
(symbol_ref:SI ("__dso_handle"))
] 6))) [9 S4 A8])) 29 {*m68k.md:976} (nil)
(expr_list:REG_EQUAL (symbol_ref:SI ("__dso_handle"))
(nil)))
(insn 34 32 35 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
(mem/f:SI (reg/f:SI 35) [6 __dso_handle+0 S4 A16])) -1 (insn_list 32 (nil))
(expr_list:REG_DEAD (reg/f:SI 35)
(nil)))
So it looks like PIC is starting to happen (at least the UNSPEC 6 part is...).
I've tromped through recog(), and indeed the insn is not matched.
Does anyone have an idea as to why? It should be equivilent to:
move.l (%r35),-(%sp)
where %r35 is whatever register (reg:SI 53) will end up in. I would
have expected this to be matched by:
;; General case of fullword move. The register constraints
;; force integer constants in range for a moveq to be reloaded
;; if they are headed for memory.
(define_insn ""
;; Notes: make sure no alternative allows g vs g.
;; We don't allow f-regs since fixed point cannot go in them.
;; We do allow y and x regs since fixed point is allowed in them.
[(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<,y,!*x*r*m")
(match_operand:SI 1 "general_src_operand" "daymSKT,n,i,g,*x*r*m"))]
"!TARGET_5200"
"*
{
if (which_alternative == 4)
return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
return \"fpmove%.l %x1,%x0\";
return output_move_simode (operands);
}")
which allows nonimmediate_operand on the destination(which whould match the
push), and general_src_operand on the source(which should match the
register indirect).
Any help is appreciated.
--
Peter Barada Peter.Barada@motorola.com
Wizard 781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola) 781-270-0193 (fax)