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: 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)


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